ForeignKeyConstraint FK_

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 81 Antworten in diesem Thema. Der letzte Beitrag () ist von Amelie.

    ForeignKeyConstraint FK_

    Hallo

    Ich komme hier nicht weiter.
    Habe mir eine DB gemacht, darin mehrere Tabellen und dann nach dem "4-views-Vorbild" von @ErfinderDesRades die Beziehungen erstmal für 2 Tabellen erstellt.
    Wenn ich nun einen Datensatz speichern möchte bekomme ich die Fehlermeldung. Siehe Anhang.
    Ohne die Beziehungen speichern alle Forms die jeweiligen Daten korrekt ab.

    Ich sehe den Fehler nicht. ;(

    VB.NET-Quellcode

    1. Public Class frm_Kundeneu
    2. Private Sub frm_Kundeneu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Me.KundenTableAdapter.Fill(Me.Db_earUI.Kunden)
    4. End Sub
    5. Private Sub speichern()
    6. Me.Validate()
    7. Me.KundenBindingSource.EndEdit()
    8. Me.TableAdapterManager.UpdateAll(Me.Db_earUI)
    9. End Sub
    10. Private Sub btn_OK_Click(sender As Object, e As EventArgs) Handles btn_OK.Click
    11. Select Case MsgBox("Sicher ohne speichern schließen?", MsgBoxStyle.YesNo, )
    12. Case MsgBoxResult.Yes
    13. Try
    14. Dim frm1 As frm_kundemain
    15. frm1 = CType(Me.Parent, frm_kundemain)
    16. MessageBox.Show("Änderungen werden verworfen!", "Information", MessageBoxButtons.OK)
    17. Me.Close()
    18. Catch ex As Exception
    19. MessageBox.Show(ex.Message)
    20. End Try
    21. Case MsgBoxResult.No
    22. speichern()
    23. MessageBox.Show("Daten gespeichert!", "Information", MessageBoxButtons.OK)
    24. Dim frm1 As frm_kundemain
    25. frm1 = CType(Me.Parent, frm_kundemain)
    26. Me.Close()
    27. End Select
    28. End Sub
    29. End Class
    Bilder
    • fehler1.jpg

      404,34 kB, 879×795, 213 mal angesehen
    • fehler2.jpg

      468,1 kB, 1.011×576, 194 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    jo ich weisses nicht genau.
    ich glaub eher nicht, dass der Fehler bei jedem Datensatz kommt, der gespeichert werden soll.

    Ich kenn mich auch nicht so mittm TableAdapterManager aus, obs da iwelche Konfiguration gibt, um den - in Abstimmung mit der Konfiguration der Relationen in der Datenbank - zum Laufen zu bringen.

    Ich verfolge eine Strategie, die die Löschweitergabe auf der Datenbank mit-nutzt, und damit kommt TableAdapterManager nicht klar.
    So jdfs. meine damaligen Forschungen - seither habich mit dem Teil nix mehr zu tun.

    ErfinderDesRades schrieb:

    jo ich weisses nicht genau.
    So jdfs. meine damaligen Forschungen - seither habich mit dem Teil nix mehr zu tun.


    Hey
    hmm das hilft mir jetzt nicht viel??? ;)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    ​Me.KundenBindingSource.EndEdit()
    führt doch die ausstehenden Änderungen auf die zugrundeliegende Datenquelle aus? (Kenn mich mit dem TableAdapterManager auch nicht aus).

    Aber die Fehlermeldung sagt doch aus, dass du in 'Kunden' einen Fremdschlüssel eintragen möchtest, den es in 'Angebot' als Primärschlüssel nicht (bzw. noch nicht) gibt.

    Maffi schrieb:

    ​Me.KundenBindingSource.EndEdit()

    Aber die Fehlermeldung sagt doch aus, dass du in 'Kunden' einen Fremdschlüssel eintragen möchtest, den es in 'Angebot' als Primärschlüssel nicht (bzw. noch nicht) gibt.


    Ja aber die Schlüssel gibt es doch.
    Ich glaube aber ich habe das Problem gefunden. Ich teste gerade noch etliche male Datensätze anzulegen.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Wie gesagt - TableAdapterManager ist für mich ein anderes Dorf - aber ...

    ... ein EndEdit auf die Bindingsource von Angebot würde ja die Datensätze in die Table Angebot eintragen - also auch die PK's die man im Table Kunden als FK's braucht.
    Ein darauffolgendes EndEdit auf die Bindingsource von Kunden würde danach die Datensätze im Table Kunden (mit den PK's aus Angebot als FK in Kunden) eintragen.

    Und abschließend sehr wahrscheinlich dieses TableAdapterManager.UpdateAll();

    Maffi schrieb:



    ... ein EndEdit auf die Bindingsource von Angebot würde ja die Datensätze in die Table Angebot....


    Ähmmm :)
    Kannst du mir das mal an einem CodeBeispiel zeigen.. verstehe grade nicht.
    Danke
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Ich habe das jetzt mal nachgebaut und bei mir funktioniert alles so weit.

    Allerdings bekomme ich die gleiche Fehlermeldung, wenn ich im Table 'Kunden' im Attribut 'AngebID' eine ID vergeben möchte, die es im Table 'Angebote' im Attribut 'Id' nicht gibt.

    Wenn du noch mal deine Fehlermeldung anschaust, steht dort sogar, dass du im Table 'Kunden' im Attribut 'AngebID' die 1234 vergeben wolltest. Ich glaube nicht das im Table 'Angebot' ein Datensatz vorhanden ist der den Primärschlüssel 'ID'=1234 hat.

    Deswegen denke ich dass es einfach eine Fehleingabe im FK war.

    Meinen Code brauche ich nicht zeigen (denke ich) da ich nur ein Form_Load habe wo die TableAdapter.Fill drinnen sind und die Methode ....NavigatorSaveItem_Click mit den Bindingsource.Endedit.
    @Maffi

    Die "12345" war ein Wert der in die 2 Tabellen eingetragen werden sollte.
    Bei "Kunden // AngeboID" und bei "Angebote // ID"

    Fehleingabe bei FK??? ( Was ist FK? )
    Code würde mir schon helfen wenn es bei dir soweit klappt ;)
    DANKE
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Was ist FK?
    ForeignKey. Die KundenTabelle will eine AngebotsID. Also eine Angebotstabellenzeile mit einer bestimmten ID. Da die ID aus einer anderen Tabelle erwartet wird, ist von ForeignKey (Fremdschlüssel) die Rede.

    Amelie schrieb:

    Fehleingabe bei FK???
    Na, ich hoffe doch mal, dass diese ID automatisch vergeben wird, sonst wird schnell mal Mus draus, wenn man da was manuell eingeben muss. Wenn was manuell eingegeben werden muss, dann muss sichergestellt werden, dass dies 1. nur einmal gemacht werden muss, obwohl 2 Tabellen bearbeitet werden und 2. dass diese ID nur 1x in der Angebotstabelle existiert. Sonst ist schnell Land unter.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:



    Bei "Kunden // AngeboID" und bei "Angebote // ID" <===== Ist Identisch beide INT32


    Ja das wird automatisch gemacht, diese ID vergeben. ;)


    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Amelie“ ()

    @Maffi
    @VaporiZed

    Habe nun mal etwas geschafft, alles noch unaufgeräumt aber das kommt noch.

    Die " JOINTABLE " wird zwar mit den richtigen Headers zur Laufzeit erstellt aber nicht mit den Daten aus den beiden anderen Tabellen gefüllt. FehlerMeldungen kommen keine.
    Etwas ratlos bin.

    VB.NET-Quellcode

    1. Public conn As New SqlConnection("Data Source=(LocalDB)\v11.0;AttachDbFilename=B:\Dokumente\Projekte2013\EAR_UI\EAR_UI\db_earUI.mdf;Integrated Security=True")
    2. Public cmd As New SqlCommand("Select Angebote.AngebID, AngebNr, Angebot, firstName, lastName, KundenNr, Kunden.AngebID from Angebote INNER JOIN Kunden on Angebote.AngebID = Kunden.AngebID", conn)
    3. Public DA As New SqlDataAdapter
    4. Public Jointable As New DataTable
    5. Private Sub frm_kundemain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. Me.AngeboteTableAdapter.Fill(Me.Db_earUI.Angebote)
    7. Me.KundenTableAdapter.Fill(Me.Db_earUI.Kunden)
    8. '--------------
    9. conn.Open()
    10. DA.SelectCommand = cmd
    11. Jointable.Clear()
    12. DA.Fill(Jointable)
    13. DGView1.DataSource = Jointable
    14. conn.Close()
    Bilder
    • error3.jpg

      210,58 kB, 1.084×648, 180 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Laut Post#1 ist die Kunden-Tabelle über die AngebID mit der ID der Angebote-Tabelle verbunden, was auch richtig wär; aber nicht mit der AngebID in der Angebote-Tabelle. Aber nun ist laut den Screenshots in der Angebote-Tabelle in AngebID die gleiche wie in der Kundentabelle. Wenn der erste Satz bzw. die Tabellenbeziehung stimmt, dann ist das jetzt dargestellte inhaltlich falsch! In der Kunden-Tabelle muss bei AngebID 1 stehen, nicht 76414!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich bin mal so dreist zu behaupten, dass das mit der Nutzung wie bei ner Rechnungsnummer ist: ID = intern für das Programm, AngebID = das für den Kunden, was auf dem Angebotszettel draufsteht, also »Unser Angebot {AngebID} für Sie umfasst folgende Produkte:« Das sollte aber m.E. auch so bleiben, z.B. für den Fall, dass aufgrund interner Prozesse ein Angebot nachgebessert werden muss und dann dieselbe AngebID verwendet werden muss, aber sowohl das erste, ggf. fehlerhafte als auch das nachgebesserte Angebot in der Datenbank drinstehen muss. Dann haben beide Angebote dieselbe AngebID, aber eine andere ID.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Sam85
    @VaporiZed

    VaporiZed schrieb:

    Ich bin mal so dreist zu behaupten,..... Das sollte aber m.E. auch so bleiben, z.B. für den Fall, dass aufgrund interner Prozesse ein Angebot nachgebessert werden muss.....

    Genau so habe ich mir das gedacht.
    Noch zur Info. Das ist ein reines Übungsprojekt. ;)

    Ich habe nun mal die DB und die Tabellen neu gestaltet; denke das wird dann übersichtlicher.
    Werde ich im laufe des Tages mal posten und dann nachfragen.

    ------------------
    So ich habe mal eine neue DB mit Tabellen und FK erstellt.
    Ist das so richtig? ;)
    Bilder
    • db1.jpg

      389,88 kB, 1.204×618, 165 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Amelie“ () aus folgendem Grund: Neue DB

    Ist das so richtig?


    Es kommt darauf an was du genau machen möchtest. In deinen Model bekommt derselbe Kunde, wenn er mehrere Angebote hat, keine eindeutige ID.
    Wenn du möchtest, dass du denselben Kunden mehrere Angebote geben kannst, brauchst du eine m:n Beziehung.
    Dein momentanes Model ist eine 1:n Beziehung.

    Die 'KundenNr' in der Tabelle 'Angebot' ist Redundant, da sie in der Tabelle 'Kunden' bereits gespeichert wird.
    Die 'AngebotNr' in der Tabelle 'Angebot' darf kein 'int' sein, da in deinen vorherigen Bild dort 'AG-76414' eingetragen ist.

    Die 'AngebotNr' in der Tabelle 'Kunden' sollte 'AngebotID' heißen, da sie ja der Fremdschlüssel (Primärschlüssel 'ID') aus der Tabelle 'Angebote' ist.
    Die 'KundenNr' in der Tabelle 'Kunden' darf auch kein 'int' sein, da in deinen vorherigen Bild dort 'KU-76414' eingetragen ist.

    Wenn man jetzt noch die Normalisierung beachtet, gehört die Adresse und das Telefon in separate Tabellen, da diese mit dem Konzept 'Kunde' nicht direkt etwas zu tun haben.

    Blödes Beispiel: Ein und derselbe Kunde besitzt 2 Wohnadressen und hat ein Festnetztelefon und zwei Handy's.

    Aber wie oben bereits geschrieben - Es kommt darauf an was du genau haben (Abbilden) möchtest.

    Maffi schrieb:


    Es kommt darauf an was du genau machen möchtest.


    Hallo
    Erstmal vielen Dank für deine Erklärungen.
    Das mit den "Vorzeichen"; da hatte ich erst die Idee, eindeutige Nummer, jeweils für Kunde, Angebot und Rechnung zu erstellen und dann als Vorzeichen eben nur " RE, KU AG " für Rechnungen etc und dann immer eine fortlaufende Zahl anzuhängen.
    Beispiel:
    KU-4711 ==>AG-4711-1 und AG-4711-2 und dann RE-4711-1 ..... usw.

    Das habe ich aber aufgegeben. Die Vorzeichen könnte ich auch später im Code vor den jeweiligen Nr setzen lassen???

    Ich muss mein Tabellengerüst wohl nochmals überarbeiten. OK, das mit den vielen TelNr usw ist erstmal nicht so wichtig. Erstmal den Plan und Code so zu erstellen, das ich ein Kunde anlegen kann und ihm dann ein oder mehrere "Angebote" und eine "Rechnung" erstellen kann. ;)

    Also muss ich ein Design entwicklen welches so ausschaut.
    Einen Kunde anlegen:

    Eintrag der eindeutigen ID ==> Tabelle Kunden (P-Key) ?
    Eintrag der KundenNr ==> Tabelle Kunden
    .....Weitere Kundendaten ==> Tabelle Kunden ( z.B. Adresse usw... )

    Eintrag der eindeutigen ID ==> Tabelle Angebote (P-Key) ?
    Eintrag der AngebotNr ==> Tabelle Angebote
    .....Weitere Angebotdaten ==> Tabelle Angebote ( z.B. Datum wann Angebot erstellt usw... )


    Aber hier fehlt doch jetzt ein Bezug zu den beiden Tabellen oder?
    Muss nicht in einer von beiden Tabellen ein Wert (Schlüssel) vorhanden sein der auch in der anderen steckt, den ich dann verbinde?
    Also : ( PK ===> FK ) ???

    Bin für jede weitere Hilfe Dankbar. ;)

    -----------------------------------------------------------------------
    Edit: nach lesen usw. habe ich nun dieses Konzept erstellt. siehe Anhang normalisierung.jpg
    Bilder
    • normalisierung.jpg

      107,47 kB, 661×365, 165 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Amelie“ () aus folgendem Grund: Anhang normalisierung

    Wobei du bei diesem Model jetzt in der Tabelle 'Angebote1' und 'Kunden1' jeweils die Attribute 'ID' weglassen kannst, da die Attribute 'AuftragNr' und 'KundenNr' als Primärschlüssel festgelegt sind.
    Aber es geht jetzt schon mal in die richtige Richtung. :)

    Wichtig ist, dass es jetzt klar ist, dass du einem Kunden 0, 1 oder mehrere Angebote zuweisen möchtest und ...
    ... soweit es kein absolut personalisiertes Angebot ist, dieses auch eventuell mehreren Kunden zuweisen könntest.

    Kurz zurück zu deinen ersten Model. (1:n Beziehung)



    Dadurch dass der PK aus der Tabelle 'Angebote' als FK in der Tabelle 'Kunden' pro Datensatz (Zeile) nur EIN mal vergeben werden kann, siehst du mehrere Datensätze von beiden Kunden, da jeder mehrere Angebote hat.
    Abgesehn davon bekommt ja jeder neue Datensatz wieder eine eindeutige ID (PK).

    Max Muster und Herbert Huber wären nicht mehr eindeutig durch deren PK identifizierbar.

    ​Aber hier fehlt doch jetzt ein Bezug zu den beiden Tabellen oder? Muss nicht in einer von beiden Tabellen ein Wert (Schlüssel) vorhanden sein der auch in der anderen steckt, den ich dann verbinde? Also : ( PK ===> FK ) ???


    Dafür brauchen wir eine Zwischentabelle in der die jeweiligen Kombinationen (Kunden mit Angeboten) zusammengefasst werden. (m:n Beziehung)



    In dieser Zwischentabelle 'AngebotKunde' werden in den Attributen 'ID_Angebot' und 'ID_Kunde' die jeweiligen Primärschlüssel aus den Tabellen 'Angebot' und 'Kunde' als Fremdschlüssel eingetragen.



    Ich habe als Beispiel das Angebot 'Angebot-111' genommen, welches dem Kunden 'Herbert Koc' (sollte Koch heißen - ist mir aber ein Buchstabe abhanden gekommen :) ) und dem Kunden 'Franz Huber' zugewiesen wurde.

    Genauso umgekehrt sieht man das 'Max Muster' zwei verschiedene Angebote hat.

    (Der Code ist zwar C#, sollte aber lesbar sein)

    Und das script (bei mir ist es aus SQL-Server) dazu.



    Mit diesem Model hast du jedes Angebot - jeden Kunden - und in der Zwischentabelle jede Kombination aus Angebot und Kunde mit einer eindeutigen ID identifizierbar.