2013-06-07 16 views
13

Ich versuche, die Grundlagen von Entity Framework zu verstehen, und ich habe eine Frage über die Set <> -Methode auf DbContext. Ich verwende ein erstes Datenbankmodell für die folgende Frage.Entity Framework: Wann Set <>

Angenommen, ich habe eine ActivityLog-Datenbank, mit der ich unter anderem eine Nachricht abrufen kann (z. B. eine NLog-Nachricht). Ich konnte einige Code schreiben, alle Nachrichten wie diese herausziehen:

using (var entities = new ActivityLogEntities()) 
    foreach (var log in entities.AcitivityLogs) 
     Console.WriteLine(log.Message); 

Allerdings konnte ich erreichen, auch die gleiche Sache dies zu tun:

using (var entities = new ActivityLogEntities()) 
    foreach (var message in entities.Set<ActivityLog>().Select(entity => entity.Message)) 
     Console.WriteLine(message); 

Meine Frage ist, was ist der Unterschied zwischen diesen beiden Aussagen ist? Wann ist es sinnvoller, einen über den anderen zu verwenden? Oder ist das nur eine Frage der persönlichen Vorliebe?

+1

Wenn Sie keine 'ActivityLogs' -Eigenschaft haben, können Sie die' ActivityLogs' -Eigenschaft nicht verwenden. Das mag wie eine nutzlose Antwort erscheinen, aber ich hatte Situationen, in denen ich auf einen 'DbSet ' für einen Typ zugreifen musste, der absichtlich keine direkte Eigenschaft für die Entitäten dieses Typs hatte. Dies beantwortet jedoch nicht die Frage, welche zu verwenden ist, wenn beides möglich ist. – hvd

+0

@hvd vereinbart, aber es ist ziemlich selten zu Typen nicht durch den Kontext verwiesen (und es ist nicht ganz trivial zu tun) –

+0

@LukeMcGregor Betrachten Sie öffentliche Klasse Order {öffentliche ICollection Lines {get; einstellen; }} public class OrderLine {} public class Kontext {public IDbSet Orders {get; privates Set; }} '. Es ist keine zusätzliche Arbeit erforderlich, um dies zu erreichen, und es macht normalerweise keinen Sinn, auf 'OrderLines' ohne die Befehle zuzugreifen. Warum also sollte ich eine 'OrderLines'-Eigenschaft auf der Kontext-Ebene hinzufügen? – hvd

Antwort

10

Es gibt keinen signifikanten Unterschied. Im ersten Fall haben Sie so etwas wie:

class MyContext : DbContext 
{ 
    public DbSet<AcitivityLog> AcitivityLogs { get; set; } 
} 

Wenn Kontext schafft, es DbSet<T> Lese-/Schreibeigenschaften für öffentliche aussieht, und tut dies (Pseudocode):

dbSetProperty = Set<EntityType>(); 

Aber , gibt es Fälle, wenn Sie:

1) möchte keine öffentlichen Eigenschaften für alle von Ihnen Entitätstypen machen;
2) kenne nicht alle Entitätstypen bei der Entwurfszeit des Kontextes.

In diesen Fällen ist Set<T> die einzige Möglichkeit, den richtigen Entitätssatz zu erhalten.

+0

Ich vermute, im Falle Ihres zweiten Beispiels würde dies nur für automatisch generierte gelten? – Serberuss

+0

@Serberuss: Nein, nicht nur. Einer der Vorteile der 'DbContext'-API besteht darin, dass Sie den Kontext dynamisch erstellen können (im Gegensatz zum traditionellen Ansatz mit' ObjectContex' und EDM-Designer). Dies ermöglicht es, das Datenmodell viel flexibler zu gestalten, aber es hat einen Nebeneffekt: Die Liste der Entitätstypen ist nicht statisch und der Entwickler des 'DbContext'-Vorfahren kann einfach nicht über jeden Entitätstyp Bescheid wissen. – Dennis

+0

Leider funktioniert das zweite Beispiel nicht. Ich folgende Art von Fehler: 'Die Entität ist nicht Teil des Modells für den aktuellen Kontext.Ich habe keine Ahnung, was ich falsch mache. – krypru

1

Wenn Sie die erzeugte DbContext Klasse betrachten, werden Sie sehen, dass AcitivityLogs nur ein DbSet<ActivityLog> ist.

So sind sie das gleiche Gleiche. Es ist nur die eingegebene Definition Ihres DbSet.

8

Der einzige Grund, warum ich jemals Set<T> verwendet habe, ist, wenn Sie auf einen Typ einwirken, den Sie nicht kennen, zB einen generischen Einsatz.

Heres ein Beispiel aus my generic repository:

public void AddOnSave(T entity) 
    { 
    ctx.Set<T>.Add(entity); 
    } 

es für normale Sachen Verwendung macht nur den Code weniger lesbar IMHO

+0

['AddOrUpdate'] (https://msdn.microsoft.com/en-us/library/dn217945 (v = vs.113) .aspx)? – oCcSking

+0

@oCcSking nicht sicher, was du meinst? –

+0

Eigentlich habe ich Ihre Antwort nicht richtig verstanden, verwirrt mit dem Fall, dass Sie nicht sicher sind, ob Sie hinzufügen oder aktualisieren, dann können Sie AddOrUpdate verwenden – oCcSking

Verwandte Themen