2014-10-21 17 views
5

Amaç kayıtlarının listesini almak SonraEF Tür yürütmesinde

var records = db.Set<UserAccount>().ToList(); 

döngü

foreach (var record in records) 
{ 
    // do something with the record 
} 

Ama o kadar, çalışma zamanı belirli tip değil zorundadır Ben türler arasında döngü ve ben "UserAccount" örneğini bilmiyorum. Sadece Tip/TipOf mu? Bu açıklamanın dibinde

Bir yöntemini Sanırım bazı varlıklarla bir DBContext oluşturduk

çalışmak için bir yol bulamıyorum loopAllEntities var.

public class MyEntities : DbContext 
{ 
    public DbSet<UserAccount> UserAccounts { get; set;} 
    public DbSet<UserRole> UserRoles { get; set; } 
    public DbSet<UserAccountRole> UserAccountRoles { get; set; } 
} 

çıkışını kontrol etmek Tipi listesini Tanımlı:

public static List<Type> ModelListSorted() 
{ 
    List<Type> modelListSorted = new List<Type>(); 
    modelListSorted.Add(typeof(UserRole)); 
    modelListSorted.Add(typeof(UserAccountRole)); 
    modelListSorted.Add(typeof(UserAccount)); 
    return modelListSorted; 
} 

Sorun

public static loopAllEntities() 
{ 
    List<Type> modelListSorted = ModelHelper.ModelListSorted(); 

    foreach (Type type in modelListSorted) 
    {   
     var records = ????? // get a list of records in the current table from type. 
     foreach (var record in records) 
     { 
      // do something with the record 
     } 
    } 
} 

cevap

1

görünüyor :-(Çalışır yapmak için bir yol bulamıyorum nerede altındadır Neredeyse orada olduğunuz gibi, aşağıdaki gibi bir şey yapabilmeniz gerekir:

public static void loopAllEntities(DbContext dbContext) 
    { 
     List<Type> modelListSorted = ModelHelper.ModelListSorted(); 

     foreach (Type type in modelListSorted) 
     { 
      var records = dbContext.Set(type); 
      // do something with the set here 
     } 
    } 

Bu, üzerinde çalışmak için jenerik olmayan bir küme alacaktır. Ne yapmak istediğinize bağlıdır, çünkü bu sette herhangi bir tip yoktur, biraz zor olabilir, belki de bir taban tipine veya arayüzüne çalışabilir mi?

Düzenleme: Yorum yapmak için yeterli saygınlığım yok, ancak Mayoors çözümü, jenerik olmayan bir tür kullanmadan istediğiniz şeyi alabiliyor ve tüm koleksiyonu ön tarafa taşıyor.

+0

Teşekkür ederiz @Matt. Bu sadece ihtiyacım olan şeydi :-) – pladekusken

1

Başlangıçta, yalnızca bir türle öğe alamadığınızı düşünüyordum, ancak Matt'in yanıtına bakarak yapabilirsiniz. Yani, bu cevap muhtemelen en iyisi değil ...

Temel fikir, her bir IEnumerable<object> modelimizde bir Varlık olan IEnumerable<object> listesini almaktır. Düz eski object'u kullanmamızın nedeni, birbiriyle ilişkili olmayan farklı varlıkları iade etmesini istediğimiz içindir. Ancak, bu çok da kötü değil, çünkü her nesnenin içine girdiğinizde, gerekiyorsa bunu belirli bir varlığa atabilirsiniz.

private static List<IEnumerable<object>> AllEntities(MyEntities db) 
{ 
    List<IEnumerable<object>> list = new List<IEnumerable<object>>(); 
    list.Add(db.UserRole); 
    list.Add(db.UserAccountRole); 
    list.Add(db.UserAccount); 

    return list; 
} 

biz aslında bu yöntemin dışında meydana IEnumerables, döngü başladığında o alışacaklar çünkü bizim DbContext geçmek:

İlk olarak, bu listeyi döndüren bir yöntem yaratacaksınız. Yani, burada DbContext'u ve bunun Dispose'unu oluşturamayız.

using (var db = GetMyEntities()) 
{ 
    List<IEnumerable<object>> recordsList = AllEntities(db); 
    foreach (IEnumerable<object> records in recordsList) 
    { 
     foreach (object record in records) 
     { 
      // Do something with record. 
      // If you need to access type-specific properties, 
      // do something like below 
      if (record is UserAccount) 
      { 
       UserAccount account = (UserAccount)record; 
       Console.WriteLine("User Name: " + account.UserName); 
      } 
     } 
    } 
} 

Ve o kadar:

Biz şimdi bizim tarafın bütün döngü için bu yöntemi kullanabilirsiniz. SQL açısından, dış foreach döngüsünün her yinelemesi için SELECT * FROM TABLE_NAME gibi bir şey yapacaktır.Bu, List<IEnumerable<object>>'un içindeki verileri önbelleğe almamak anlamına gelir ve AllEntities'u her kullandığınızda, veritabanından yeni veriler alır.

+0

Cevabınız için teşekkürler. Kodundan ilham aldım ve bence başka bir bağlamda kullanabilirim. Cevap @matt, ihtiyacım olan şeydi :-) – pladekusken

0

Bunun eski bir soru olduğunu biliyorum, ancak soru EF sürümünü belirtmiyor ve önerilen çözüm Entity Framework Core için artık çalışmıyor (DbContext, en az tarihte EF çekirdeğinde jenerik olmayan küme yöntemine sahip değil. bu cevabın). Yine de Jon Skeet'in cevabını kullanarak this question'a kadar bir çalışma uzantısı yöntemine sahip olabilirsiniz. Kolaylık için kodum aşağıda eklenmiştir.

public static IQueryable Set(this DbContext context, Type T) 
    { 

     // Get the generic type definition 
     MethodInfo method = typeof(DbContext).GetMethod(nameof(DbContext.Set), BindingFlags.Public | BindingFlags.Instance); 

     // Build a method with the specific type argument you're interested in 
     method = method.MakeGenericMethod(T); 

     return method.Invoke(context, null) as IQueryable; 
    } 
+0

Girdiğin için teşekkürler :-) Çok ilginç görünüyor! – pladekusken