Eine abhängige Eigenschaft in einer ReferentialConstraint wird einer vom Speicher generierten Spalte zugeordnet

98

Ich erhalte diesen Fehler beim Schreiben in die Datenbank:

Eine abhängige Eigenschaft in einer ReferentialConstraint wird einer vom Speicher generierten Spalte zugeordnet. Spalte: 'PaymentId'.

public bool PayForItem(int terminalId, double paymentAmount, 
      eNums.MasterCategoryEnum  mastercategoryEnum, int CategoryId, int CategoryItemId)
    {

        using (var dbEntities = new DatabaseAccess.Schema.EntityModel())
        {
            int pinnumber = 0;
            long pinid = 1; //getPinId(terminalId,ref pinnumber) ;
            var payment = new DatabaseAccess.Schema.Payment();
            payment.CategoryId = CategoryId;
            payment.ItemCategoryId = CategoryItemId;
            payment.PaymentAmount = (decimal)paymentAmount;
            payment.TerminalId = terminalId;
            payment.PinId = pinid;

            payment.HSBCResponseCode = "";
            payment.DateActivated = DateTime.Now;
            payment.PaymentString = "Payment";
            payment.PromotionalOfferId = 1;
            payment.PaymentStatusId = (int)eNums.PaymentStatus.Paid;

            //payment.PaymentId = 1;

            dbEntities.AddToPayments(payment);
            dbEntities.SaveChanges();
        }
        return true;
    }

Das Schema lautet:

Geben Sie hier die Bildbeschreibung ein

Walisischer König
quelle

Antworten:

180

Ist es möglich, dass Sie eine schlechte Spaltenbeziehung zwischen Ihren Tabellen definiert haben? verschiedene Spalten und eine wurde als autonumerisch festgelegt.

Es ist mir passiert.

ju4nj3
quelle
55
Ich habe fälschlicherweise einen meiner Fremdschlüssel zu einer Identität gemacht (automatische Inkrementierung). Dies ist der Fehler, den ich bekommen habe.
Jocull
3
Doh! Ich hatte den Fremdschlüsselteil der Beziehung als Standard von SQL Server 2008 Management Studio beibehalten. Dies waren die Primärschlüsselfelder der untergeordneten Tabelle und nicht die Spalte, die ich erstellt hatte, um den Fremdschlüsselwert zu enthalten.
Robaker
12
Wenn Sie die Ausnahme im Quick Watch-Fenster (dh (e as System.Data.Entity.Infrastructure.DbUpdateException).Entries) überprüfen , können Sie sehen, welche Tabelle den Primärschlüssel enthält, auf den verwiesen wird.
28.
17
Wäre es nicht cool, wenn die EF-Fehlermeldungen nur das Problem angeben würden, anstatt Gobbledy-Gook auszuspucken?
AR
Ich habe diese Abfrage verwendet, um alle Beziehungen in einer Ansicht anzuzeigen. Stackoverflow.com/questions/8094156/…
Dave
47

Dieser Fehler besagt, dass Sie eine nicht unterstützte Beziehung verwenden oder einen Fehler in Ihrer Zuordnung haben. Ihr Code hat höchstwahrscheinlich absolut nichts mit dem Fehler zu tun.

Der Fehler bedeutet, dass Sie eine Beziehung zwischen Entitäten haben, bei denen die Fremdschlüsseleigenschaft in der abhängigen Entität als generierter Speicher definiert ist. Im Geschäft generierte Eigenschaften werden in die Datenbank eingetragen. EF unterstützt das Speichern von generierten Eigenschaften als Fremdschlüssel (sowie berechnete Eigenschaften in Primärschlüsseln) nicht.

Ladislav Mrnka
quelle
2
Ich kann die Zeile in SQL Server mit den gleichen Informationen hinzufügen. Wenn Sie Store Generated sagen, können Sie ein Beispiel geben?
Welsh King
1
EF ist kein SQL Server. Es hat seine eigene Einschränkung. Finden Sie einfach heraus, wo Sie eine von DB generierte FK-Eigenschaft verwenden, PaymentIDund rufen Sie sie auf.
Ladislav Mrnka
OK, wir haben eine Tabelle mit der Zahlungshistorie, in der die Zahlungs-ID als Fremdschlüssel angegeben ist. Muss ich dort eine Zeile hinzufügen?
Welsh King
Es geht nicht um das Hinzufügen einer Zeile, sondern um die Definition der Spalte. Wie setzen Sie diese Spalte?
Ladislav Mrnka
Klicken Sie einfach auf das Beziehungsmodell in Visual Studio und ich erhalte den Namen 'Zahlung' kann nicht in Typ 'Zahlung' verwendet werden. Mitgliedsnamen dürfen nicht mit ihrem umschließenden Typ identisch sein. Irgendwelche Ideen
Welsh King
8

Ich hatte das gleiche Problem. Basierend auf den hier gegebenen Antworten konnte ich es verfolgen und lösen, aber ich hatte ein seltsames Problem, das unten beschrieben wurde - es könnte jemandem in der Zukunft helfen.

In meinen abhängigen Tabellen wurden die Fremdschlüsselspalten auf StoreGeneratedPattern = "Identity" gesetzt. Ich musste es auf "Keine" ändern. Leider hat dies im Designer überhaupt nicht funktioniert.

Ich habe in der vom Designer generierten XML (SSDL) gesucht und diese Eigenschaften waren noch vorhanden, sodass ich sie manuell entfernt habe. Ich musste auch die Spalten in der Datenbank reparieren (entfernen Sie die Identität (1,1) aus CREATE TABLE SQL)

Danach ging das Problem weg.

surfen
quelle
Danke für diesen Tipp. Durch Ändern des Felds im Designer von "Identität" in "Keine" wurde dies an einer Stelle im EDMX geändert, jedoch nicht an der anderen Stelle. Daher wurde der Fehler immer noch angezeigt, bis ich die EDMX-Datei selbst bearbeitet habe. Leider wurde EntityFramework dann verrückt und versuchte, verwandte Entitäten wieder in andere Tabellen einzufügen, aber dennoch war es eine Hilfe bei der Umgehung dieser Fehlermeldung.
FTWinston
6

Ich hatte das gleiche Problem und nach einigem Eingraben in das Tabellendesign in SQL Server stellte ich fest, dass ich fälschlicherweise den Primärschlüssel der Tabelle auch als Fremdschlüssel festgelegt habe.

Entwurfsablauf für SQL Server-Tabellen

In diesem Bild sehen Sie, dass JobID der Primärschlüssel der Tabelle, aber auch fälschlicherweise ein Fremdschlüssel ist.

Manish Bhakuni
quelle
2

Mein Problem wurde durch die redundante Definition des Primärschlüssels in der Konfiguration verursacht.

this
   .Property(p => p.Id)
   .HasColumnName(@"id")
   .IsRequired()
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) // this is redundant when you want to configure a One-to-Zero-or-One relationship
   .HasColumnType("int");

Entfernen Sie diese Linie

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


Beispiel http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

Dies reicht aus, um die Beziehung zu definieren

// Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
            .HasOptional(s => s.Address) // Mark Address property optional in Student entity
            .WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student
Piotr
quelle
1

Überprüfen Sie die Beziehung zwischen Zahlung und den anderen Tabellen / Entitäten erneut. Einschließlich derjenigen, die PaymentId nicht enthalten sollten, da sich dort das Problem höchstwahrscheinlich versteckt.

Beim Erstellen von Fremdschlüsseln in SQL Server Management Studio wird standardmäßig der Primärschlüssel verwendet. Diese Standardeinstellung wird beim Ändern der übergeordneten Tabelle zurückgesetzt. Achten Sie daher darauf, die Werte im Fenster "Tabellen und Spalten" in der richtigen Reihenfolge zu ändern.

Nachdem Sie die problematische Beziehung behoben haben, besteht eine gute Chance, dass eine einfache "Aktualisierung" des Modells die fehlerhafte Beziehung nicht korrekt aus dem Modell entfernt und Sie den gleichen Fehler auch nach der " Korrektur " erhalten. Tun Sie dies im Modell selbst, bevor Sie eine Aktualisierung durchführen. (Ich habe das auf die harte Tour herausgefunden.)

Kennzeichen
quelle
1

Wenn Sie Ihre Beziehungen überprüft haben und dort gut sind.

Löschen Sie die Tabelle im edmx und aktualisieren Sie sie dann aus der Datenbank. Dadurch sparen Sie sich das Update manuell.

rickjr82
quelle
Wirklich danke für Ihren Rat, ich habe 1 Stunde damit verbracht, meine Datenbank zu validieren, aber nachdem sie entfernt und dann aktualisiert wurde, ist alles in Ordnung.
Tấn Nguyên
1

Für mich war es ein falsch platzierter Fremdschlüssel in der Tabelle, aber selbst nachdem ich die Tabelle geändert hatte, um ihn zu reparieren, funktionierte er immer noch nicht. Sie müssen die EDMX-Dateien aktualisieren (und nicht genug, um die Tabelle aus dem Modell zu "aktualisieren", müssen Sie die Tabelle entfernen und erneut im Modell hinzufügen).

knocte
quelle
1

Neben der akzeptierte Antwort, wenn Sie EF Reverse - POCO - Generator oder ein anderes Werkzeug verwenden , die Ihre POCO erzeugt, stellen Sie sicher , dass Sie regenerieren sie!

adam0101
quelle
Vergessen Sie niemals, Ihr benutzerdefiniertes T4-Tool (mit den POCOs) erneut auszuführen, nachdem Sie Ihren externen DB-first EF-Modellgenerator (mit den Kontexten) geändert haben ... ÜBERHAUPT! XD (hätte genauso gut verrückt werden können -.- ')
Shockwaver
0

In meinem Fall wurde das Problem durch eine wechselseitige 1: 1-Beziehung verursacht:

class Foo{
[Key]
Id
[ForeignKey]
BarId
...
}
class Bar{
[Key]
Id
[ForeignKey]
FooId
...
}

Ich musste einfach einen der beiden Fremdschlüssel entfernen (sowieso nicht notwendig).

wecky
quelle
0

In meinem Fall war es einfach so, dass ich keine richtigen Berechtigungen für die Datenbank hatte. Ich hatte nur Lesezugriff gelesen und das Entity-Framework gab mir einen ReferentialConstraint-Fehler, der mich abschreckte. Zusätzliche Schreibberechtigungen hinzugefügt und alles war gut.

Mdhattr
quelle
0

In meinem Fall hatte ich eine datenbankgenerierte Eigenschaft und eine ForeignKey-Navigationseigenschaft eingerichtet, um auf eine 1: 1-bezogene Tabelle zu verweisen.

Dies konnte ich nicht entfernen. Ich musste in der Lage sein, sowohl den Primärschlüssel der Entität als datenbankgeneriert festzulegen als auch die 1: 1-Tabelle als Navigationseigenschaft zu referenzieren.

Ich bin mir nicht sicher, ob dies für andere gleich ist, aber dieses Problem trat nur beim Erstellen einer neuen Entität auf. Beim Lesen oder Bearbeiten vorhandener Entitäten wurde das Problem nicht angezeigt. Daher habe ich das Problem umgangen, indem ich eine geerbte Version meines Kontexts erstellt und verwendet habe Die Fluent-Methode zum Ausschalten der Navigationseigenschaft beim Erstellen.

Meine ursprüngliche Entität sah also so aus:

public partial class MyEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid id{ get; set; }


    // Navigation
    [ForeignKey("id")]
    public PathEntity Path { get; set; }
}

Also habe ich einen speziellen vererbten Kontext erstellt, der so aussah:

    private class _navPropInhibitingContext : EF.ApplicationDBContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<MyEntity>()
                .Ignore(e => e.Path);

        }
    }

und änderte dann den Code, der die neue Entität erstellt hat, um den Benutzer zum neuen Kontexttyp zu machen

    using (var specialContext = new _navPropInhibitingContext())
    {
        var dbModel = new MyEntity() 
        {
            ...
        };

        specialContext.MyEntity.Add(dbModel);
        await specialContext.SaveChangesAsync();
    }

Hoffe das hilft jemandem

Chris Terry
quelle
0

In meinem Fall ID-Feld, das FK nur im Entity Framework hat, wurde die Eigenschaft "StoreGeneratedPattern" auf "Itentity" anstelle von "None" gesetzt.

Lev K.
quelle