2012-04-04 5 views
1

Ich komme aus TSQL + C# Land und habe versucht, an LINQ und EF anzupassen. Viele-zu-viele-Beziehungen haben mich gestolpert. Ich habe Modelle mit Viele-zu-Viele-Beziehungen, die ich aus einer Datenbank abfragen möchte. Wie zum Beispiel:Entity Framework: Get Model mit verknüpften Modellen in vielen zu vielen Beziehung

 class Product{ 
     public int ID {get;set;} 
     public string ProductName {get;set;} 
     public virtual ICollection<Tag> Tags {get;set;} 
    } 

    class Tag { 
     public int ID {get;set;} 
     public string TagName {get;set;} 
     public virtual ICollection<Product> Products {get;set;} 

    } 

ich aus mir dem DbContext, ein Produkt zu erhalten, bin in der Lage, und später holt dann diese zugehörige Tags wie es ist:

// product exists in memory as a Product with an empty product.Tags 

var query = from p in db.Product 
      from t in db.Tags 
      where p.ID == product.ID 
      select p.Tags; 

Dann kann ich die product.Tags zuweisen mit die abgerufenen Tags. Offensichtlich ist dies im Umgang mit mehreren Produkten sehr ineffizient, wenn ich für jedes Produkt abfragen muss.

Mit Linq und EF möchte ich in der Lage sein, ein Produkt mit allen zugehörigen Tags in einem Umlauf in die Datenbank zu bekommen. Außerdem möchte ich in der Lage sein, alle Produkte und ihre zugehörigen Tags (oder eine gefilterte Liste von Produkten) zu erhalten. Wie würde die linq aussehen?

Edit:

Ok, nachdem einige um mehr Hantieren, ich habe diese bekam:

var query = db.Product.Include("Tags") 
      .Where(p => p.Tags.Any(t => t.Products.Select(m => m.ID).Contains(p.ID))); 

Das ist fast, was ich brauche. Die Ergebnisse sind alle Produkte mit Tags. Fehlt sind die Produkte, die keine Tags haben. Ich denke, dies ist das Äquivalent eines SQL Inner Joins. Ich möchte verlassen äußere die Tags zu dem Produkt beitreten und alle Produkte mit Tags optional zurückgeben. Wie erhalten Sie alle Produkte mit den zugehörigen Tags, ohne Produkte auszuschließen, die keine Tags haben?

Bearbeiten:

Das war einfacher als ich dachte.

var query2 = db.Product.Include("Tags").DefaultIfEmpty(); 

Dies wird alle Produkte und ihre jeweiligen Tags, einschließlich der Produkte ohne Tags. Hoffentlich funktioniert es aus den richtigen Gründen ...

Antwort

0

Der Zweck der Verwendung eines objekt-relationalen Mappers wie EF ist, dass es Beziehungen für Sie mappt. Wenn Sie manuell Objekte mit Fremdschlüsseln in der Datenbank verknüpfen, tun Sie es falsch.

Siehe meine Frage Why use LINQ Join on a simple one-many relationship?

Die richtige Antwort einfach context.Products.Include("Tags") ist, was wird auto-magisch verbinden Produkte und Marken für Sie. Dies ist buchstäblich der größte (einzige?) Vorteil der Verwendung eines ORM.

Verwandte Themen