我使用System.Linq.Dynamic.Core
动态地将lambda表达式添加到EF中的查询。
我还希望能够按名称选择表格。我找到了这个答案:
https://stackoverflow.com/a/28101268/657477
但它在asp.net core 2.0中无效。我无法使用DbSet
我必须在错误消息中使用DbSet<TEntity>
。
我希望能够db.GetTable("Namespace.MyTable").Where(...)
我该怎么做?
答案 0 :(得分:19)
首先,你需要从名称中获取实体的类型(如果你有类型,只需直接使用它)。您可以使用反射,但EF Core的正确方法可能是使用FindEntityType
方法。
获得类型后,问题是如何获取相应的[input]="true"
。 EF Core目前不提供类似于EF6的非通用DbSet<T>
方法,主要是因为没有非泛型Set(Type)
类。但是,通过使用一些EF Core内部结构,您仍然可以获得相应的DbSet
DbSet<T>
:
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);
}
}
方法:
Set<T>
在这两种情况下,您都可以使用以下内容:
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(...)
答案 1 :(得分:2)
EF Core不再具有非通用的.set方法,但是此扩展类使使用动态linq基于字符串查询表变得容易
public static class DbContextExtensions
{
public static IQueryable<Object> Set(this DbContext _context, Type t)
{
return (IQueryable<Object>)_context.GetType().GetMethod("Set").MakeGenericMethod(t).Invoke(_context, null);
}
public static IQueryable<Object> Set(this DbContext _context, String table)
{
Type TableType = _context.GetType().Assembly.GetExportedTypes().FirstOrDefault(t => t.Name == table);
IQueryable<Object> ObjectContext = _context.Set(TableTypeDictionary[table]);
return ObjectContext;
}
}
}
用法:
IQueryable<Object> query = db.Set("TableName");
// Filter against "query" variable below...
List<Object> result = query.ToList();
// or use further dynamic Linq
IQueryable<Object> query = db.Set("TableName").Where("t => t.TableFilter == \"MyFilter\"");