2017-02-17 2 views
0

Ich versuche NullableGuid in Entity Framework zu verwenden, aber wenn ich die Änderung zu übernehmen habe ich versucht Validierungsnachricht bin immer durch Fremdschlüssel ist null, ich habe unter Domain-Klasse, DomainType Klasse hat Kind DomainCustomField: -Entity Framework mit Nullable Guid? Validierungsfehler verursacht

DomainType.cs

public class DomainType 
{ 
    public Guid? Id 
    { 
     get; 
     set; 
    } 
    private IList<DomainCustomField> _domainCustomFields; 

    public string Name 
    { 
     get; 
     set; 
    } 

    public Guid? AccountId 
    { 
     get; 
     set; 
    } 

    public virtual IList<DomainCustomField> DomainCustomFields 
    { 
     get 
     { 
      return this._domainCustomFields; 
     } 
     set 
     { 
      this._domainCustomFields = value; 
     } 
    } 
} 

DomainCustomField.cs

public class DomainCustomField 
{ 
     public Guid? Id 
     { 
       get; 
       set; 
     } 
     public string Name 
     { 
      get; 
      set; 
     } 
     public Guid? DomainTypeId 
     { 
      get; 
      set; 
     } 
} 

unten ist Mapping: -

modelBuilder.Domain<DomainCustomField>().HasKey((DomainCustomField p) => new 
      { 
       p.Id, 
       p.DomainTypeId 
      }); 
      modelBuilder.Domain<DomainCustomField>() 
       .Property(p => p.Id) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
      modelBuilder.Domain<DomainType>() 
       .HasMany(p => p.DomainCustomFields) 
       .WithRequired() 
       .HasForeignKey<Guid?>(x => x.DomainTypeId); 

unten ist Beispielcode, den ich versuchte einzufügen.

DomainType domainType = new DomainType() 
     { 
      AccountId = customer.Id 
     }; 
     domainType.DomainCustomFields.Add(new DomainCustomField() 
     { 
      Name = "Test" 
     }); 
     Workspace.Add<DomainType>(domainType); 
     Workspace.CommitChanges(); 

Fehler: - Validierungsfehler für DomainTypeId erforderlich ist

in dem gleichen Code, wenn ich Guid?-Guid in ID-Variable ändern korrekt dann seine Arbeit. Ich weiß nicht, wie ich mit nullableGuid umgehen soll. Muss ich den Elternschlüssel in der Kinderreferenz manuell setzen? wie funktioniert es dann im Fall von Guid?

Hinweis: - Ich benutze Guid, weil ich mit verteilte Datenbank arbeite, wo ID aus mehreren Quellsystemen generieren kann. Ich verwende Guid?, weil standardmäßig Guid generieren 00000000-0000-0000-0000-000000000000 für leere Guid, die Datenbankgröße wachsen kann.

+0

Haben Sie versucht, (add Navigations Eigenschaft 'DomainType' im Modell)' .HasOptional' -> 'modelBuilder.Domain () .Property (p => p.Id) ..HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity) .HasOptional (p => Domain Name) .. HasForeignKey (x => x.DomainTypeId) ' – Developer

+0

Ja, ich habe versucht, HasOptional. Es ist nicht dieses Problem. Die Eltern-ID wird nicht in die untergeordnete Variable gesetzt, obwohl sie verknüpft sind. –

+0

Dieser Fehler macht für mich Sinn, vielleicht bin ich hier total falsch. Wenn Ihr Primärschlüssel "nullable" ist (nicht sicher, wie der primäre Schlüssel "nullable" funktioniert), legt die EF möglicherweise keine richtige Beziehung für die untergeordnete Sammlung fest (da die übergeordnete ID null ist). – Developer

Antwort

-1

Sie können eine Standard-ID für die Datenbank verwenden. GUID? gespeichert als ein Feld in der Tabelle.

+0

Bitte beachten Sie die Anmerkung in der Frage erwähnt "standardmäßig Guid generieren 00000000-0000-0000-0000-000000000000 für leere Guid, die Datenbankgröße wachsen kann" –

+0

Sie können nicht Nullable Typ für Primärschlüssel verwenden. Verwenden Sie Integer-Typ für Primärschlüssel und GUID? als ein Feld in der Tabelle. – npsavin

0

Das Problem hat nichts mit Guid Art zu tun (das gleiches mit int passieren wird), aber die Diskrepanz zwischen der NULL-Zulässigkeit des Objekttypen in der Einheit verwendet, und die tatsächlichen NULL-Zulässigkeit der Immobilie durch das Modell impliziert.

Erstens erfordert EF, dass PKs nicht nullfähig sein dürfen. Daher DomainType.Id, DomainCustomField.Id und DomainCustomField.DomainTypeId sind effektiv nicht nulable (es ist unklar, warum Sie DomainTypeId in der PK der DomainCustomField haben, die bereits einzigartige Datenbank generiert haben Id, aber das ist eine andere Geschichte).

Zweitens, DomainCustomField.DomainTypeId ist effektiv nicht nullfähig, weil Sie angegeben haben, dass - der WithRequired() Teil der FK-Beziehungskonfiguration.

Jetzt versucht EF, diese Diskrepanzen zu beheben. Wenn Sie sich die generierte Migration ansehen, werden Sie feststellen, dass die entsprechenden Datenbanktabellenspalten aller fraglichen Felder nicht nullfähig sind. Jedoch (nichts ist perfekt, wissen Sie), ein Teil des EF-Codes ist nicht in der Lage, diese Diskrepanz und damit die Ausnahme zu behandeln.

Mit diesem gesagt, halten Sie die NULL-Fähigkeit der Modelleigenschaften immer synchron mit ihrer tatsächlichen NULL-Fähigkeit. In diesem Fall müssen beide 3 Eigenschaften nicht nullbar sein (d. H. Vom Typ Guid).

P.S.Was ist mit der Notiz Ich verwende Guid?, weil standardmäßig Guid generieren 00000000-0000-0000-0000-000000000000 für leere Guid, die Datenbankgröße wachsen kann., ich habe keine Ahnung was meinst du damit. Die Nullliterität der Klasseneigenschaft hat nichts mit der Datenbankgröße zu tun, und wie bereits erwähnt, sind die entsprechenden Datenbanktabellenspalten für diese Konfiguration sowieso nicht nullbar.

Beachten Sie auch, dass Sie in Ihrem Beispiel die Id des neuen DomainType vergessen haben, was Sie tun sollten, da es nicht automatisch generiert wird.

1

Ich nehme einen etwas anderen Ansatz in meiner Antwort und versuche Ihnen zu sagen, was Sie ändern müssen, um ein funktionierendes Beispiel zu erhalten.

Wie jemand darauf hingewiesen hat, dürfen eindeutige Bezeichner nicht Nullable sein, so dass das Id Feld in DomainType ein Guid sein sollte. Außerdem müssen Sie das Id-Feld in DomainCustomField ändern. Diese benötigen möglicherweise einen leeren Konstruktor, nur um ein neues Guid zu erstellen.

Zweitens ist der Fremdschlüssel in Ihrem anderen Objekt Guid? DomainTypeId völlig in Ordnung, das kann bleiben, aber wenn es bleibt, müssen Sie Ihre Konfiguration ändern.

In diesem Block haben Sie angegeben, dass die Eigenschaft erforderlich ist?

modelBuilder.Domain<DomainType>() 
       .HasMany(p => p.DomainCustomFields) 
       .WithRequired() 
       .HasForeignKey<Guid?>(x => x.DomainTypeId); 

So einfach machen es optional;

modelBuilder.Domain<DomainType>() 
       .HasMany(p => p.DomainCustomFields) 
       .WithOptional() 
       .HasForeignKey<Guid?>(x => x.DomainTypeId); 

Das sollte Ihre Probleme lösen. Noch Fragen lassen Sie mich wissen :)

+0

Dies war mein Problem gerade heute, ich hatte die Guid-Spalte als optional angegeben, aber ich habe es nicht für die viele Zeilen wie oben getan, erinnert mich daran, es auf WithOptional setzen dieses Problem für mich behoben. Wenn ich WithRequired hätte, dann wäre das erzeugte sql seltsam und würde keine Guids zurückgeben, die null waren, z. guid = null. Eine leere Liste zurückgegeben, obwohl die Datenbank einige Null-GUID-Werte enthält. – Andrew