繁体   English   中英

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

[英]How to cast DbSet<T> to List<T>

鉴于以下简化的实体框架 6 上下文,我正在尝试使用实体填充列表,但在如何通过反射进行转换(我相信)方面存在问题。

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 等)的情况下执行此操作。

IDBSet继承自IQueryable<TEntity>IEnumerable<TEntity>IQueryableIEnumerable ,因此您无法直接将其转换为列表。 你可以得到一个List<TEntity>中的所有实体DBSet虽然使用.ToList().ToListAsync()

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

//dont forget using System.Linq;
using (var context = new FooContext())
{
   IQueryable<FooClass> rtn = from temp  in context.Foo select temp;
   var list = rtn.ToList();
}

除了VicYam的回答,这里有一个更简单的方法,详细解释。

添加System.Linq命名空间后,您不再需要获取IQueryable ,然后转换为List 相反,您将获得DbSet对象上的扩展方法。

这是什么意思? 您可以简单地返回DbSet ,因为它继承自IEnumerable 然后,消费者(可能是开发者)可以执行.ToList或他们可能需要的任何其他列表类型。

最简单的

这将按DbSet返回DbSet ,它已经从IEnumerable继承, IEnumerable是一个列表类型,然后可以转换为List

List<ObjectType> list = new List<ObjectType>();
using (var context = new FooContext())
{
    list = context.Foo;
}

替代

您可以立即从IEnumerable转换为List

using (var context = new FooContext())
{
    var list = context.Foo.ToList();
}

仍然想要VicYam的回答但是作为一条线?

using (var context = new FooContext())
{
    var list = context.Foo.AsQueryable().ToList();
}

你不能施展它。 只要创建一个新List<T>从你DbSet通过ToListAsync<T>()IQueryable经由同步或异步简单枚举它ToList()

另外,我认为更好地为您的场景创建具体的实现。 现在为EF创建。 例如,当你开始使用NHibernate时,为它创建测试,依此类推。 对于将来的支持将更加简单,然后尝试创建通用的东西,这对于修复和调试来说将更加复杂。

仅供参考,您确定不需要这些集成测试吗? 也许更好的测试您的映射/实现正在使用您的数据库。 我认为这将是更重要的部分。 当然,如果你之前没有这样做过。

private StudentDatabaseEntities db = new StudentDatabaseEntities();

public List<StudentDatabaseDbTableModel> AllProducts()
{
    return db.StudentDatabaseDbTableModel.ToList();
}   

db.StudentDatabaseDbTableModel的类型为DbSet。 ToList是DbSet类中的一个方法。 ToList方法将DbSet类型的对象转换为List类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM