动态访问EF Core 2.0中的表

我正在使用System.Linq.Dynamic.Core将lambda表达式动态添加到EF中的查询。

我也希望能够按名称选择表格。 我找到了这个答案:

https://stackoverflow.com/a/28101268/657477

但它不适用于asp.net core 2.0。 我不能使用DbSet我必须使用DbSet它在错误消息中说。

我希望能够做db.GetTable("Namespace.MyTable").Where(...)

我怎样才能做到这一点?

首先,您需要从名称中获取实体的类型(如果您有类型,只需直接使用它)。 您可以使用reflection,但EF Core的正确方法可能是使用FindEntityType方法。

一旦你有了类型,问题是如何获得相应的DbSet 。 EF Core目前不提供类似于DbSet非genericsSet(Type)方法,主要是因为没有非genericsDbSet类。 但是你可以通过使用一些EF Core内部结构获得相应的DbSet作为IQueryable

 using System; using System.Linq; using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore { public static partial class CustomExtensions { public static IQueryable Query(this DbContext context, string entityName) => context.Query(context.Model.FindEntityType(entityName).ClrType); public static IQueryable Query(this DbContext context, Type entityType) => (IQueryable)((IDbSetCache)context).GetOrAddSet(context.GetDependencies().SetSource, entityType); } } 

或通过reflection调用通用的Set方法:

 using System; using System.Linq; using System.Reflection; namespace Microsoft.EntityFrameworkCore { public static partial class CustomExtensions { public static IQueryable Query(this DbContext context, string entityName) => context.Query(context.Model.FindEntityType(entityName).ClrType); static readonly MethodInfo SetMethod = typeof(DbContext).GetMethod(nameof(DbContext.Set)); public static IQueryable Query(this DbContext context, Type entityType) => (IQueryable)SetMethod.MakeGenericMethod(entityType).Invoke(context, null); } } 

在这两种情况下,您都可以使用以下内容:

 db.Query("Namespace.MyTable").Where(...) 

要么

 db.Query(typeof(MyTable)).Where(...) 

EF Core不再具有非generics.set方法,但是此扩展类使得使用动态linq基于字符串查询表变得容易

 public static class DbContextExtensions { public static IQueryable Set(this DbContext _context, Type t) { return (IQueryable)_context.GetType().GetMethod("Set").MakeGenericMethod(t).Invoke(_context, null); } public static IQueryable Set(this DbContext _context, String table) { Type TableType = _context.GetType().Assembly.GetExportedTypes().FirstOrDefault(t => t.Name == table); IQueryable ObjectContext = _context.Set(TableTypeDictionary[table]); return ObjectContext; } } 

}

用法:

 IQueryable query = db.Set("TableName"); // Filter against "query" variable below... List result = query.ToList(); // or use further dynamic Linq IQueryable query = db.Set("TableName").Where("t => t.TableFilter == \"MyFilter\"");