如何将DbSet 转换为List

鉴于以下简化的Entity Framework 6上下文,我尝试使用实体填充List,但是如何通过reflection进行转换(我相信)有问题。

public class FooContext : DbContext { public virtual IDbSet 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 to List or List? var list = value as List(); //... } } } 

我正在为实用程序方法执行此操作,以进行一些集成测试。 我试图这样做,而不使用直接内联SQL调用(使用SqlConnection和SqlCommand等)来访问数据库(因为数据存储可能会更改为Oracle等)。

IDBSetinheritance自IQueryableIEnumerableIQueryableIEnumerable ,因此您无法直接将其强制转换为列表。 您可以通过使用.ToList().ToListAsync() .ToList()中所有实体的List

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

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

你不能施展它。 只需从DbSet通过ToListAsync()ToListAsync()创建一个新的List ,方法是异步枚举或简单地通过同步ToList()

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

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

 private StudentDatabaseEntities db = new StudentDatabaseEntities(); public List AllProducts() { return db.StudentDatabaseDbTableModel.ToList(); } 

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

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

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

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

最简单的

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

 List list = new List(); 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(); }