![]() |
Datenbank: XML: .NET DataSet • Version: 1.1 • Zugriff über: ADO.NET
Master-Detail Datenmanagement mit ADO.NET 1: Constraints??
Ich steh grad vollkommen auf dem Schlauch, weil ich sowas schon lange nicht mehr gemacht hab und ich das einfach nicht mehr hinbekomme.
Was ich gerne hätte wäre eine kurze Erklärung (Schritt für Schritt) zu den Punkten wo ich Probleme habe. Ich habe eine ASP.NET WebForms - Anwendung. Dort will ich ein paar Daten zur Authentifizierung und zum Ablegen auf dem Webserver speichern und nutzen. Da ich aber keine Datenbank hintendran haben will habe ich mir gedacht, ich nutze nur das DataSet und dessen WriteXml / ReadXml bzw. WriteXmlSchmema / ReadXmlSchema Funktionalität. Gedacht, getan: Ich habe nun ein WebForm mit einem DataSet und im DataSet habe ich folgende Tabellen definiert: table Benutzer: userId: String password: String table Texte: userId: String headline: String text: String Pflichtfelder: alle bis auf text. Keys: table Benutzer: userId table Texte: userId und Headline als zusammengesetzter Primärschlüssel. Hier das zugehörige Schema:
XML-Code:
userId in der Tabelle TExte ist freilich ein Fremdschlüssel zur userId in der Tabelle Benutzer, so dass man Dateneinträge mit eigener headline einem User eindeutig zuordnen kann.
<?xml version="1.0" standalone="yes"?>
<xs:schema id="dsTexte" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="dsTexte" msdata:IsDataSet="true" msdata:Locale="de-DE"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="Texte"> <xs:complexType> <xs:sequence> <xs:element name="userId" type="xs:string" /> <xs:element name="headline" type="xs:string" /> <xs:element name="text" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Benutzer"> <xs:complexType> <xs:sequence> <xs:element name="userId" type="xs:string" /> <xs:element name="password" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1"> <xs:selector xpath=".//Benutzer" /> <xs:field xpath="userId" /> </xs:unique> <xs:keyref name="user2texte" refer="Constraint1"> <xs:selector xpath=".//Texte" /> <xs:field xpath="userId" /> </xs:keyref> </xs:element> </xs:schema> Nun scheitere ich jedoch schon daran, Daten initial einzutragen und zu speichern. Ich will auf einer Admin-Page erstmal Benutzer anlegen können. Dazu habe ich mir dort 2 Text-Controls draufgepappt und einen Anlegen-Button, und die beiden TextControls mit DataBindings auf die Tabelle User gehängt. Im Quellcode des Speichern-Events steht:
Delphi-Quellcode:
Wenn ich nun schon das ausführe, dann speichert er mir die Daten zwar in einem Xml-File:
procedure TWebForm1.btnAddUser_Click(sender: System.Object; e: System.EventArgs);
var tmp: DataRow; begin tmp := dataSet.Tables['Benutzer'].NewRow; tmp['userId'] := txtUserId.Text; tmp['password'] := txtPassword.Text; dataSet.Tables['Benutzer'].Rows.Add(tmp); dataSet.WriteXml(page.MapPath('.') + '\.data.xml'); dataSet.ReadXml(page.MapPath('.') + '\.data.xml'); DataBind; end;
XML-Code:
Beim wieder einlesen der geänderten Datensätze schmeisst er mir jedoch folgende Exception:
<?xml version="1.0" standalone="yes"?>
<dsTexte> <Benutzer> <userId>test</userId> <password>test</password> </Benutzer> </dsTexte>
Code:
Also: Wo habe ich da einen Bock geschossen und wo muss ich anlangen damit schonmal das geht?
Serverfehler in der Anwendung '/WebNotes'.
-------------------------------------------------------------------------------- Einschränkungen konnten nicht aktiviert werden. Mindestens eine Zeile enthält Werte die die Einschränkungen non-null, unique or foreign-key verletzen. Beschreibung: Beim Ausführen der aktuellen Webanforderung ist ein unverarbeiteter Fehler aufgetreten. Überprüfen Sie die Stapelüberwachung, um weitere Informationen über diesen Fehler anzuzeigen und festzustellen, wo der Fehler im Code verursacht wurde. Ausnahmedetails: System.Data.ConstraintException: Einschränkungen konnten nicht aktiviert werden. Mindestens eine Zeile enthält Werte die die Einschränkungen non-null, unique or foreign-key verletzen. Quellfehler: Zeile 88: dataSet.Tables['Benutzer'].Rows.Add(tmp); Zeile 89: dataSet.WriteXml(page.MapPath('.') + '\.data.xml'); --> Zeile 90: dataSet.ReadXml(page.MapPath('.') + '\.data.xml'); <-- Zeile 91: DataBind; Zeile 92: end; Quelldatei: c:\inetpub\wwwroot\WebNotes\adminpage.pas Zeile: 90 Stapelüberwachung: [ConstraintException: Einschränkungen konnten nicht aktiviert werden. Mindestens eine Zeile enthält Werte die die Einschränkungen non-null, unique or foreign-key verletzen.] System.Data.DataSet.FailedEnableConstraints() System.Data.DataSet.EnableConstraints() System.Data.DataSet.set_EnforceConstraints(Boolean value) System.Data.XmlDataLoader.LoadData(XmlReader reader) System.Data.DataSet.ReadXml(XmlReader reader, Boolean denyResolving) System.Data.DataSet.ReadXml(String fileName) adminpage.TWebForm1.btnAddUser_Click(Object sender, EventArgs e) in c:\inetpub\wwwroot\WebNotes\adminpage.pas:90 System.Web.UI.WebControls.Button.OnClick(EventArgs e) System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) System.Web.UI.Page.ProcessRequestMain() -------------------------------------------------------------------------------- Versionsinformationen: Microsoft .NET Framework Version:1.1.4322.2032; ASP.NET-Version:1.1.4322.2032 Dann will ich in einem zweiten Schritt - und da steige ich auch aus - über eine DropDown Box aus den verfügbaren Headlines auswählen lassen. Allerdings eingeschränkt auf den aktuell angemeldeten Benutzer. Aber ich hab da schon ne Idee das über ne View und RowFilter zu machen, wenn das nicht klappt gibts da noch nen neuen Thread dazu. Aber das hier wär schonmal wichtig, weil ich ich da echt nicht weiss woran es hängt. |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Dein Problem kann ich zwar nicht nachvollziehen, aber dein Schema ist für das was du damit machen willst unpassend. ;)
Die hast doch reine, hierarchischen XML Daten und keine relationalen Daten in einem DBMS. Warum legst du die Daten dann nicht einfach hierarchisch ab um den sinnlosen ForeignKey unnötig zu machen?
XML-Code:
Nachtrag: Wofür heißt das im Beitragseditor Formatierter XML-Quellcode? Ich kann da, bis auf xmlns, rein gar nix formatiertes erkennen... :gruebel:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="dsTexte" targetNamespace="phoenix.net/Benutzer" xmlns:mstns="phoenix.net/Benutzer" xmlns="phoenix.net/Benutzer" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="unqualified" elementFormDefault="qualified"> <xs:element name="dsTexte" msdata:IsDataSet="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Benutzer"> <xs:complexType> <xs:sequence> <xs:element msdata:IsNested="true" name="Texte" minOccurs="0"> <xs:complexType> <xs:attribute name="headline" type="xs:string" use="required"/> <xs:attribute name="text" type="xs:string" use="optional"/> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="userId" type="xs:string" use="required" /> <xs:attribute name="password" type="xs:string" use="optional"/> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1"> <xs:selector xpath=".//Benutzer"/> <xs:field xpath="userId"/> </xs:unique> </xs:element> </xs:schema> |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Zitat:
Und wieso ist mein Schema unpassend? Natürlich habe ich relationale Daten: Wenn ich einen User lösche dann soll mir das DataSet dazu selbstverständlich alle zugehörigen Einträge aus der Texte-Tabelle mitlöschen. Und zwar automatisch. Das geht natürlich nur, wenn das DataSet über die Relation dem Eintrag in der Benutzertabelle auch die Einträge in dier Texte-Tabelle zuordnen kann. Und wenn sich ein User authentifiziert, dann sollen auch nur seine Notizen angezeigt werden und nicht die von allen Usern. |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Zitat:
Ich habe das gerade mal ausprobiert und eine Mini-GUI zusammengeGUIt. Das hier kommt dabei raus und lässt sich auch wieder einlesen: (siehe screenie)
XML-Code:
Ich habe das Schema noch verändert so dass es Elemente statt Attribute benutzt. DataSets scheinen schlichtweg zu dämlich zu sein um sich an Attribute zu halten (Die generierte XML Datei war zwar wieder einlesbar aber furchtbar hässlich...)
<?xml version="1.0" standalone="yes"?>
<dsTexte xmlns="phoenix.net/Benutzer"> <Benutzer> <userId>a</userId> <Texte> <headline>eene</headline> </Texte> <Texte> <headline>meene</headline> </Texte> <Texte> <headline>muuh</headline> </Texte> </Benutzer> <Benutzer> <userId>b</userId> <Texte> <headline>1</headline> </Texte> <Texte> <headline>2</headline> <text>bla ba</text> </Texte> <Texte> <headline>3</headline> </Texte> </Benutzer> <Benutzer> <userId>c</userId> <Texte> <headline>4</headline> </Texte> <Texte> <headline>5</headline> </Texte> <Texte> <headline>6</headline> </Texte> </Benutzer> </dsTexte>
XML-Code:
Ich habe es außerdem zum Test auch mal durch XSD von .Net 1.1 gejagt: Auch dort lief alles problemlos...
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="dsTexte" targetNamespace="phoenix.net/Benutzer" xmlns:mstns="phoenix.net/Benutzer" xmlns="phoenix.net/Benutzer" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="unqualified" elementFormDefault="qualified"> <xs:element name="dsTexte" msdata:IsDataSet="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Benutzer"> <xs:complexType> <xs:sequence> <xs:element name="userId" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="password" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element msdata:IsNested="true" name="Texte" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="headline" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="text" type="xs:string" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1"> <xs:selector xpath=".//Benutzer" /> <xs:field xpath="userId" /> </xs:unique> </xs:element> </xs:schema>
Delphi-Quellcode:
var ds := new dsTexte();
var fileName := 'Texte.xml'; ds.ReadXml(fileName); for benutzer : dsTexte.BenutzerRow in ds.Benutzer do begin Console.WriteLine(benutzer.userId); for text : dsTexte.TexteRow in benutzer.GetTexteRows() do begin Console.WriteLine('-> {0}', text.headline); if not text.istextNull() then Console.WriteLine('--> {0}', text.text); end; end; ds.WriteXml(fileName); Output a -> eene -> meene -> muuh b -> 1 -> 2 --> bla ba -> 3 c -> 4 -> 5 -> 6 hui... schon wieder viel zuviel wegen einer Kleinigkeit getippt... :shock: |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Jetzt bin ich Baff. Sowas kann das DataSet? Ich meine, ich hab schon genug Probleme das so wie von mir angedacht hinzubekommen, aber wo muss ich denn da hinlangen wenn ich das auf Deine Art haben möchte?
Am besten da mal von ganz vorne Anfangen, weil ich sowas echt noch nie gesehen hab. :-o |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Jetzt hab ich doch noch nen Nachtrag, der mir heut früh gekommen ist:
Die angesprochene Lösung von Dir, Elvis (sag mal, kenn ich Dich nicht unter einem anderen Namen?, hattest Du bei den letzten Delphi-Tagen in Kassel nicht das Hotelzimmer neben mir?) klingt sehr interessant und ich würde die auch gerne ausprobieren, jetzt kommt aber das grosse Aber: Momentan landen die Daten als xml-Files auf dem Webspace. Das ist per se nicht besonders sicher und vor allem ab einer bestimmten Grösse nicht mehr sehr performant. Wenn ich die Anwendung irgendwann mal vergrössern oder gar kommerzialisieren will, will ich die Daten vielleicht wirklich in einer Datenbank (z.B. MySQL) ablegen, und für den Fall brauch ich dann meine relationale Datenablage. Deswegen würde ich jetzt gerne testweise beide Ansätze weiterverfolgen. Kannst Du mir da also bitte noch ein paar Tipps zu geben? Bei mir scheitert es ja unter anderem schon an der Navigation in den Datensätzen. Ich will auf der Webpage einen Datensatz anhand der Headline aus einer Drop-Down-Box auswählen. Aber wenn ich da die Datenbindung hinpacke, dann listet er mir von der ersten Headline alle Buchstaben in einer neuen Zeile auf... war so auch nicht gewollt. |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
*frechpush... 24h sind rum* :-o
|
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Zitat:
Spaß beiseite, habe dich schlichtweg vergessen. ;) Zitat:
Aber du kannst ja sagen wo der schuh drückt. Zitat:
Du musst nur beim Speichern in eine DB darauf achten, dass die Parameter als SourceColumn diesen versteckten Key benutzen. |
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
[/quote="Elvis"]
Zitat:
Aber du kannst ja sagen wo der schuh drückt.[/quote] Überall. Jetzt noch mehr als vorher. :cyclops: Wie bekommst Du dann ohne DataSet das Binding an die Controls hin? :gruebel: Und um ehrlich zu sein will ich die ganze Arbeit die das Dataset macht nicht nochmal selber programmieren. Hast Du mir dazu irgendwie ein Beispiel? Zitat:
|
Re: Master-Detail Datenmanagement mit ADO.NET 1: Constraints
Zitat:
DataBinding 101:
Zitat:
Delphi-Quellcode:
Grid.DataSource := ['a', 'n', 'd'];
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz