EF Core如何通过字符串类型变量查询DbContext?
动态类型查询DbContext的解决办法
你碰到的核心问题是:泛型方法的类型参数得在编译阶段确定,但type是运行时才拿到的Type对象,所以直接写Set<type>()肯定编译不通过。至于context.Set(type)本身是合法的非泛型调用,但后续调用FindAsync会因为返回的是非泛型DbSet(EF6)或者版本支持问题(EF Core),导致报错。
下面给两种可行的解决思路:
方法一:用反射调用泛型版Set和FindAsync
不管是EF6还是EF Core都能用,通用性强:
var type = Type.GetType(entityName); if (type == null) throw new Exception($"找不到类型:{entityName}"); // 获取泛型Set方法并执行 var setMethod = typeof(DbContext).GetMethod(nameof(DbContext.Set)).MakeGenericMethod(type); var dbSet = setMethod.Invoke(context, null); // 获取泛型FindAsync方法,传入实体ID参数执行 var findAsyncMethod = typeof(DbSet<>).MakeGenericType(type).GetMethod(nameof(DbSet<object>.FindAsync), new[] { typeof(object[]) }); var task = (Task)findAsyncMethod.Invoke(dbSet, new object[] { new[] { entityId } }); await task; // 取出查询结果 var entity = task.GetType().GetProperty(nameof(Task<object>.Result)).GetValue(task);
方法二:EF Core专属的非泛型调用
如果用的是EF Core,非泛型DbSet已经提供了FindAsync的重载,直接调用就行:
var type = Type.GetType(entityName); if (type == null) throw new Exception($"找不到类型:{entityName}"); var dbSet = context.Set(type); var entity = await dbSet.FindAsync(entityId); // 要是需要强类型对象,后续可以转:var typedEntity = Convert.ChangeType(entity, type);
注意:EF6的非泛型
DbSet没有异步的FindAsync,只能用同步Find或者方法一的反射方式。
补充:之前context.Set(type)报错的可能原因
- 若用的是EF6:非泛型
DbSet没有FindAsync方法,只有同步Find,所以调用FindAsync会编译报错; - 若用的是EF Core:可能没引用正确的命名空间(
Microsoft.EntityFrameworkCore),或者版本过低不支持该重载。
内容的提问来源于stack exchange,提问作者Joshua Abbott
相关产品推荐
相关产品推荐

