如何投射 DbSet<T>列出<T>

人气:399 发布:2022-10-16 标签: c# reflection casting entity-framework-6

问题描述

鉴于以下简化的 Entity Framework 6 上下文,我正在尝试使用实体填充列表,但在如何通过反射进行投射(我相信)时遇到问题.

Given the following simplified Entity Framework 6 context, I am trying to populate a List with the entities but having problems with how to cast (I believe) via reflection.

public class FooContext : DbContext
{
   public virtual IDbSet<FooClass> Foo { get; set; }    
   //...
}

public class FooClass
{
    public int Id{ get; set; }
    public string Name {get; set; }
    //...    
}

public main()
{
     using (var context = new FooContext())
     {
         var sets = typeof(FooContext).GetProperties().Where(pi => pi.PropertyType.IsInterface && pi.PropertyType.GetGenericTypeDefinition().ToString().ToLower().Contains("idbset"));

         foreach (var set in sets)
         {
             //When I debug and enumerate over 'value' the entire results are shown so I believe the reflection part is OK.
             var value = set.GetValue(context, null);

             //Always returns null. How can I cast DbSet<T> to List<object> or List<T>? 
             var list = value as List<object>();

             //...
         }
     }
}

我这样做是为了我正在做的一些集成测试的实用程序方法.我正在尝试不使用直接内联 SQL 调用(使用 SqlConnection 和 SqlCommand 等)来访问数据库(因为数据存储区可能更改为 Oracle 等).

I'm doing this for utility method for some integration testing I am doing. I am trying to do this without using direct inline SQL calls (using SqlConnection and SqlCommand etc) to access the database (as the datastore may change to Oracle etc).

推荐答案

IDBSet 继承自 IQueryable, IEnumerable, IQueryableIEnumerable,因此您不能以这种方式直接将其转换为列表.您可以通过使用 .ToList().ToListAsync() 获得 DBSet 中所有实体的 List

IDBSet inherits from IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, and IEnumerable, so you can't directly cast it to a list that way. You could get a List<TEntity> of all entities in the DBSet though by using .ToList() or .ToListAsync()

这会创建内存中所有实体的副本,因此您应该考虑直接在 DBSet 上使用 LINQ 进行操作

THis creates a copy of all entities in memory though, so you should consider operating with LINQ directly on the DBSet

852