2016-06-29 9 views
1

Ich habe ein Entity Framework Code erstes Objekt mit einem selbst referenzierenden Schlüssel. Die untergeordneten Datensätze verfügen nicht über die übergeordnete ID im selbst referenzierenden Schlüssel, wenn die Daten in die Datenbank geschrieben werden.Entity Framework selbst referenzierenden Schlüssel nicht in die Datenbank schreiben

Das Objekt hat viele weitere Eigenschaften als oben, aber ich habe für das Beispiel vereinfacht. Das ist keine viel zu viele Beziehung. Jeder Vertrag hat nur einen Elternteil, abgesehen von Rahmenverträgen ohne Eltern.

Wenn ich der Vertragsliste einen Untervertrag hinzufüge und SaveChanges für den DBContext aufruft, werden der Vertrag und der Untervertrag in die Datenbank geschrieben, wobei alle Felder korrekt sind. Abgesehen von dem Entity-Framework-generierten Feld Contract_Id, das null ist.

Ich habe ähnliche selbstreferenzierende Schlüssel, die korrekt mit anderen Klassen funktionieren, tatsächlich hat der Vertrag diese Klassen als Eigenschaften. Diese anderen Klassen funktionieren alle wie erwartet, wobei die selbstreferenzierenden Schlüssel angeben, dass das übergeordnete Objekt alle korrekt ausgefüllt ist.

Ich habe eine sehr einfache Testklasse wie oben nur mit Test vor dem Klassennamen erstellt und das funktioniert ordnungsgemäß erstellt. Ich habe einen einfachen Test mit meiner Contract-Klasse erstellt, der nicht richtig funktioniert.

Was ich gerne in der Lage wäre zu debuggen die Entity Framework SaveChanges-Methode, aber ich bin mir nicht sicher, ob das möglich ist.

Hat jemand eine Idee was zu suchen in Bezug auf was ich falsch gemacht habe oder wie man das debuggt?

+0

Mögliche Duplikat [Self- referenzierender rekursiver Beziehungscode von vielen zu vielen Entity Framework] (http://stackoverflow.com/questions/5125052/self-referencing-many-to-many-recursive-relationship-code-first-entity-framework) –

+0

@ BassamAlugili Dies ist keine Beziehung von vielen zu vielen. –

+0

Ich habe diesen Ansatz mit anderen Klassen arbeiten. Das Entitätsframework erstellt ein nullbares -Feld in der Datenbank, das die ID des übergeordneten Datensatzes enthält. Es ist diese spezielle Klasse, bei der der Ansatz nicht funktioniert. –

Antwort

1

Sie haben Ihr Unternehmen so ändern:

public class Contract 
{ 
    public Contract() 
    { 
    this.Contracts = new List<Contract>(); 
    } 
    public int Id { get; set; } 

    public int? ContractParentId 
    { 
    get; set; 
    } 

    public Contract ContractParent { get; set; } 
    public List<Contract> Contracts { get; set; } 
} 

Und verwenden Sie i t wie folgt aus:

using (var dbContext = new MyDatabaseContext(productionConnectionString)) 
{ 
    // You need this for fixup 
    var contract1 = dbContext.Contracts.Create<Contract>(); 
    var contract2 = dbContext.Contracts.Create<Contract>(); 

    dbContext.Contracts.Add(contract1); 
    dbContext.Contracts.Add(contract2); 

    contract1.Contracts.Add(contract2); 

    dbContext.SaveChanges(); 
} 

Sie haben auch Ihre DbContext zu ändern, weil es nicht möglich ist, diese Art von Beziehung in-Code zu definieren, müssen Sie zuerst Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Contract>().HasOptional(c => c.ContractParent).WithMany(c => c.Contracts).HasForeignKey(c => c.ContractParentId); 
    base.OnModelCreating(modelBuilder); 
} 
+0

Ich habe Ihre Antwort als korrekt markiert, weil es die Reihenfolge war, in der ich die Unterverträge dem Datenbankkontext hinzugefügt habe, der das Problem verursacht hat. –

+1

Es stellt sich heraus, dass wenn Sie die Unterverträge zum Rahmenvertrag hinzufügen, nachdem Sie den Rahmenvertrag dem Kontext hinzugefügt haben, die selbst referenzierenden Schlüssel nicht gefüllt werden, wenn Sie SaveChanges. Alle anderen Felder im Untervertrag werden korrekt ausgefüllt. Ich musste die zusätzliche Codezeile in OnModelCreating nicht hinzufügen, damit dies funktioniert. –

0

Try this:

Ihr Modell:

public class Contract 
{ 
    public Contract() 
    { 
     Contracts = new List<Contract>(); 
    } 


    public int Id { get; set; } 
    public virtual IList<Contract> Contracts { get; set; } 
} 

Verwendung fließend API, auf DbContext dies versuchen:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Contract>().HasMany(m => m.Contracts).WithMany(); 
} 
+0

'virtual' ist das Schlüsselwort hier! –

+0

Danke. Ich habe versucht, dass und Entity Framework eine Verknüpfungstabelle mit einer Contract_Id und Contract_Id1 erstellt und die Contract_Id aus der Tabelle Contracts entfernt. Ich habe den Test ausgeführt und die Contracts-Datensätze wurden erstellt, aber nachdem ich meinen Vertragserstellungstest ausgeführt hatte, war nichts in der Linktabelle. –

+0

BTW das ist nicht eine viel zu viele Beziehung. Jedes Kind hat nur einen Elternteil. –