EF从Type中获取运行时记录列表
目的:我需要循环所有记录,如:
var records = db.Set().ToList();
然后循环
foreach (var record in records) { // do something with the record }
但是它必须在运行时没有特定类型,因为我要遍历类型,因此不知道示例“UserAccount”。 只有Type / TypeOf?
在本说明书的底部,我有一个方法loopAllEntities ,我找不到工作方式
我用一些实体创建了一个DbContext。
public class MyEntities : DbContext { public DbSet UserAccounts { get; set;} public DbSet UserRoles { get; set; } public DbSet UserAccountRoles { get; set; } }
定义了一个Type列表来控制输出:
public static List ModelListSorted() { List modelListSorted = new List(); modelListSorted.Add(typeof(UserRole)); modelListSorted.Add(typeof(UserAccountRole)); modelListSorted.Add(typeof(UserAccount)); return modelListSorted; }
问题是在我无法找到使其工作的方法:-(
public static loopAllEntities() { List 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 } } }
看起来你几乎就在那里,你应该可以做如下的事情:
public static void loopAllEntities(DbContext dbContext) { List modelListSorted = ModelHelper.ModelListSorted(); foreach (Type type in modelListSorted) { var records = dbContext.Set(type); // do something with the set here } }
这将为您提供一个非generics集合。 它取决于你想要做什么,因为这个集合没有类型它可能会有点棘手,可能会转换为基本类型或接口使用?
编辑:我没有足够的声誉来评论,但是Mayoors解决方案可以在不使用非generics类型的情况下获得您想要的内容并预先获得整个集合。
我最初认为你不能只获得一种类型的实体,但是看看Matt的答案,你可以。 所以,这个答案可能不是最好的答案……
基本思想是获取IEnumerable
的列表,其中每个IEnumerable
是我们模型中的Entity。 我们必须使用普通旧object
的原因是因为我们希望它返回彼此不相关的不同实体。 但是,这并不是那么糟糕,因为当你循环遍历每个对象时,如果需要,可以将它转换为某个实体。
首先,我们将创建一个返回此列表的方法:
private static List> AllEntities(MyEntities db) { List> list = new List>(); list.Add(db.UserRole); list.Add(db.UserAccountRole); list.Add(db.UserAccount); return list; }
我们传入DbContext
因为当我们实际开始循环遍历此方法之外的IEnumerables
时它会被使用。 所以,我们不能在这里创建DbContext
然后Dispose
它。
我们现在可以使用此方法遍历所有实体:
using (var db = GetMyEntities()) { List> recordsList = AllEntities(db); foreach (IEnumerable
就是这样。 就SQL而言,对于外部foreach循环的每次迭代,它将执行SELECT * FROM TABLE_NAME
之类的操作。 这意味着它不会缓存List
,并且每次使用AllEntities
它都会从数据库中获取新数据。
我知道这是一个老问题,但问题并没有指定EF版本,并且提议的答案不再适用于Entity Framework Core(DbContext在EF核心中至少在此答案的日期没有非通用的set方法) 。
然而,你仍然可以使用Jon Skeet的答案来解决这个问题 。 为方便起见,我的代码在下面添加。
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; }