6

Ich sehe eine Menge von Beispielen zur Verwendung von EF Code zuerst mit POCOs verwenden, die so etwas wie dies zeigen:Soll ich Fremdschlüssel synchron mit Referenzen, wenn POCOs

public class Post 
{ 
    public int PostId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 

    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 
} 

Nun sehen Sie die Blog Eigenschaft. Sollte es nicht wie diese stattdessen sein:

private Blog blog; 
public virtual Blog Blog 
{ 
    get 
    { 
     return blog; 
    } 
    set 
    { 
     blog = value; 
     if (blog != null) 
     { 
      BlogId = blog.BlogId; 
     } 
    } 
} 

Ich meine, da Sie bereits mit dem Fremdschlüssel „verschmutzen“ Ihr Modell sind, sollen Sie nicht zumindest halten sie synchron mit der Referenz? Oder Sie sollten sich beim Lesen von Daten sowieso nicht auf BlogId verlassen (z. B. wenn Sie wissen möchten, ob eine bestimmte BlogId auf einer Liste ist). Oder vielleicht gibt es eine magische Eigenschaft auf DbContext (wie KeepForeingKeysPropertiesSyncronizedWithReferences), die das für mich tut, und ich bin der einzige traurige Programmierer, die worried darüber sind? Oder bin ich paranoid? (auch, sorry für mein schlechtes Englisch)

EDIT Entschuldigung dafür - das war wirklich eine dumme Frage. Stefan hat recht, EF macht das wirklich für dich. Ich habe das nicht gesehen, weil die Referenzen, die ich passierte, mit AsNoTracking() geladen wurden. Nur in dieser Bedingung haben Sie einen Verweis mit ID und das Feld für den foreing-Schlüssel ist 0. Solange Sie einen Verweis übergeben, der bereits im Kontext ist, sollte es funktionieren.

+1

nicht über EF wissen Sie, aber Sie hatten NHibernate verwendet würden Sie nicht in der blogid Eigenschaft setzen. – erikkallen

+0

Ich denke, dass die Möglichkeit, die BlogId zu verwenden, nett ist, also brauche ich keine Blog-Referenz und kann trotzdem die Assoziation speichern. Ich bin nur verwirrt darüber, es synchron zu halten - für mich sieht es so aus als wäre es offensichtlich, aber ich habe noch nie jemanden dabei gesehen, vielleicht irre ich mich also: / – user1526627

Antwort

1

Sie müssen das nicht per se machen, EF macht das für Sie.
Wenn Sie die unabhängige Zuordnungseigenschaft festlegen, synchronisiert EF die Fremdschlüsseleigenschaft, um Ihre Änderung widerzuspiegeln und umgekehrt. Es passiert nicht sofort automatisch, aber ich denke, das passiert nach dem Aufruf von SaveChanges, aber ich bin mir nicht sicher.
Wenn Sie wissen möchten, warum einige Leute die Fremdschlüsseleigenschaft verwenden, ist es in freistehenden Apps wie Web-Apps bequemer. Wenn Sie Ihre App skalieren müssen, kann dies auch helfen, die Leistung zu verbessern (lesen Sie dies in einem aktuellen MS-Blogpost).
Im Grunde genommen müssen Sie dies nur selbst tun, wenn Sie mischen und zusammenpassen; Wenn Sie in einer Methode die unabhängige Zuordnungseigenschaft verwenden und in einer anderen verwenden Sie die Fremdschlüsseleigenschaft.

0

Datenbank Erster Code generiert.

Es scheint, dass Sie ja tun, andernfalls erhalten Sie den folgenden Fehler.

A referentielle Integrität Einschränkungsverletzung aufgetreten: Die Eigenschaft Werte, die die Referenz-Randbedingungen definieren, nicht konsistent zwischen Haupt- und abhängigen Objekten in der Beziehung sind.

Prinzip ist Ihr Post-Objekt, abhängig davon, das Blog-Objekt.

, wenn Sie versuchen, Ihre nicht zugeordneten kontextfrei POCO zurück auf den Kontext 4.1 EF DbContext anbringt:

using (TransactionScope scope = new TransactionScope()) 
using (ITAMdbContext db = new ITAMdbContext()) 
{ 
    db.Entry(post).State = System.Data.EntityState.Unchanged; // error here 
    db.Entry(post).State = System.Data.EntityState.Modified; 
    db.SaveChnages(); 

Dieser Fehler wird durch aufgelöst ..

using (TransactionScope scope = new TransactionScope()) 
using (ITAMdbContext db = new ITAMdbContext()) 
{ 
    post.BlogId = post.Blog.BlogId; 
// fix the broken FK value, EF will not do this for 
// you, it does not know if post.BlogId or the post.Blog.BlogId should be chosen. 

    db.Entry(post).State = System.Data.EntityState.Unchanged; 
    db.Entry(post).State = System.Data.EntityState.Modified; 
    db.SaveChnages(); 

tun es Ihren Weg ist gültig wenn Ihre POCO-Objekte nicht automatisch generiert werden.

Der Grund, warum Sie Post auf Unchanged setzen und dann auf Modified setzen, liegt am ersten Entry().Ein auf ein Objekt gesetzter Zustand kaskadiert den gleichen Zustand für alle untergeordneten Objekte! schrecklich, aber so scheint es zu funktionieren. dann, wenn Sie es erneut aufrufen, ändert es nur das Post-Objekt. Dies verhindert, dass untergeordnete Objekte geändert oder hinzugefügt werden.

EDIT: Das ist nicht mehr erforderlich, ihre getan für Sie

Verwandte Themen