2016-01-06 24 views
6

I özellikleri olarak iki nesne (User, PrimaryNode) ile bir nesne olması, hem de potansiyel olarak boş olabilir, aşağıya bakınız:Varlık Çerçeve ObjectQuery.Include()

public class Item 
{ 
    [Key] 
    public int ItemId { get; set; } 
    public string ItemName { get; set; } 
    public Node PrimaryNode { get; set; } 
    public User User { get; set; } 
} 

I doldurmak için varlık Framework 6 kullanıyorum Item nesnesi ve zincirleme kullanılarak, içindeki PrimaryNode ve User nesnelerini doldurması gerekir. Yukarıdaki örnekte i.User sonra item değişken boş null ise

using (var db = new MyContext()) 
{ 
    var item = db.Items.Include(i => i.User).Include(n => n.PrimaryNode).FirstOrDefault(i => i.ItemId == id); 
} 

:

zincirli ilk önce boş bir nesne, örneğin boş olarak bütün nesne döner sahiptir dahil

. Hem alt nesneleri hem de bir alt nesne boşsa, üst nesne ve diğer alt nesne hala doldurulacak şekilde doldurmanın en iyi yolu nedir?

+3

"PrimaryNode" ve "User" öğesini sanal yapın ve bunları 'Item' seçeneğine isteğe bağlı olarak eşleyin. –

+0

@octavioccl tarafından yapılan ifadeye katılıyorum - sorgunuzda yanlış bir şey yok. Testlerimde, bu sorgu, Öğeye bağlı bir Kullanıcı nesnesi olmasa bile, Düğüm nesnesini doldurur. –

+0

Şimdi onaylayabilirim, yukarıdaki yaklaşımda yanlış bir şey yok, karmaşık bir sınıfın ne olduğunu basitleştirdim. Benim durumumda, bir User nesnesine sahip olmanın yanı sıra, bir UserId özelliği de vardı (bazı çevrelerde önerdiğim gibi - kullanıcı nesnesini yüklemek zorunda kalmadan kimliği alabilirsiniz) - aslında Soruna neden olan bu özellik, ayarlandığı şekilde sorgunun, Kullanıcı tablosuna bir iç birleştirme olmasıyla sonuçlandı. Özür dilerim ve cevaplar için teşekkürler. –

cevap

1

Ben senin sorunu Include görüşmeleri nedeniyle olduğunu düşünmüyorum. documentation ile uygun olarak: Bu tür bir yöntem olup olmadığını

Bu uzantı metodu, IQueryable kaynak nesnenin Include(String) yöntemi çağırır. Kaynak IQueryable eşleşen bir yöntem yoksa , o zaman bu yöntem hiçbir şey yapar. Başka bir deyişle

çevrilmiş olacak:

var item = db.Items.Include("User").Include("PrimaryNode").FirstOrDefault(i => i.ItemId == id); 

Sorum şu, size DB bir düzgün Users içinde mevcut satırlarla ilişkili olduğu id ile Item ve PrimaryNodes tablolar var eminiz ?. Sonunda Include yöntemini çağırdığınızda, bir birleşime dönüştürülecektir, dolayısıyla ilişkinizin FK'si bu referansla PK ile eşleşmiyorsa, sorgunuz beklediğiniz şeyi geri getirmemelidir. Eğer ilgili özelliklerini yüklemek için başka varyantı denemek istiyorsanız

Neyse, sen Explicit Loading kullanabilirsiniz: Diğerleri de söylediğim gibi

var item = db.Items.FirstOrDefault(i => i.ItemId == id); 
context.Entry(item).Reference(p => p.PrimaryNode).Load(); 
context.Entry(item).Reference(p => p.User).Load(); 
+0

Aynı zamanda Lambdas'ı da kullanabileceğinizi unutmayın. db.Items.Include (öğe => Item.User). Bunu getiriyorum çünkü biraz daha refactor dostu. – Cameron

+0

Açık Yükleme örneğinin veritabanına üç çağrıyla sonuçlanacağını düşünüyor muyum? Zincirleme İçerikleri kullanmak, veritabanına birleştirmelerle tek bir çağrı yapar. –

1

Ben onun durumuna int Yavaş yükleniyor kullanırsanız daha iyi olacağını düşünüyorum. Sonra

public class Item 
{ 
    [Key] 
    public int ItemId { get; set; } 
    public string ItemName { get; set; } 
    public virtual Node PrimaryNode { get; set; } 
    public virtual User User { get; set; } 
} 

Ve: Sadece User ve sanal PrimaryNode yapmak

var db = new MyContext(); 
var item = db.Items.FirstOrDefault(i => i.ItemId == id); 
+0

Öneriniz için teşekkürler. Bu benim senaryoda işe yaramaz, eğer Tembel yükleme düzgün bir şekilde anlaşılırsa, bağlantısız bir senaryoda çalışıyorum. Ben db'den veri alıyorum ve görüntülenmek üzere bir web sayfasına dönüyorum. –

+0

@AndyE ... Rica ederim. Temsili yükleme, bir varlığın veya varlıklar topluluğunun, ilk olarak kuruluşa/varlığa atıfta bulunduğu bir mülke erişildiği zaman otomatik olarak veri tabanından yükleneceği işlemdir. –

0

, senin sorunun dahildir nedeniyle olmadığını düşünüyorum. Ancak, aşağıdaki yöntemin değeri olduğunu düşünüyorum. Zincirleme içeriğiyle yaptığınız şeye işlevsel olarak eşdeğerdir, ancak kodun kullanıcının nezdinde net olmasını sağlamak da dahil olmak üzere çeşitli faydaları olduğunu düşünüyorum.

Extension yöntemlerinde yerleştirilebilir içerir: aşağıdaki gibi Sonra

using System.Data.Entity; 
using System.Linq; 

namespace Stackoverflow 
{ 
    public static class EntityExtensions 
    { 
     public static IQueryable<Item> IncludePrimaryNode(this IQueryable<Item> query) 
     { 
      // eager loading if this extension method is used 
      return query.Include(item => item.PrimaryNode); 
     } 

     public static IQueryable<Item> IncludeUser(this IQueryable<Item> query) 
     { 
      // eager loading if this extension method is used 
      return query.Include(item => item.User); 
     } 
    } 
} 

, uzantıları kullanabilirsiniz:

using (var db = new MyContext()) 
{ 
    var itemQuery = db.Items.IncludeUser(); 

    itemQuery = itemQuery.IncludePrimaryNode(); 

    var item = itemQuery.FirstOrDefault(i => i.Id == 1); 
} 

Aynı şeyi yapmanın başka bir yolu, ama ben gibi açıklık kodu ekler.

İlgili konular