C# EF Core 2.0中的动态访问表

C# EF Core 2.0中的动态访问表,c#,linq,asp.net-core,entity-framework-core,C#,Linq,Asp.net Core,Entity Framework Core,我正在使用System.Linq.Dynamic.Core将lambda表达式动态添加到EF中的查询中 我还希望能够按名称选择表。我找到了这个答案: 但它在asp.net core 2.0中不起作用。我不能使用DbSet我必须使用DbSet它在错误消息中说 我希望能够执行db.GetTable(“Namespace.MyTable”)。其中(…) 如何实现这一点?首先,您需要从名称中获取实体的类型(如果您拥有该类型,只需直接使用它)。您可以使用反射,但EF Core的正确方法可能是使用方法 一

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

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

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

我希望能够执行
db.GetTable(“Namespace.MyTable”)。其中(…)


如何实现这一点?

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

一旦有了类型,问题是如何获得相应的
DbSet
。EF Core目前没有提供类似于EF6的非通用
Set(Type)
方法,主要是因为没有非通用
DbSet
类。但是,您仍然可以通过使用一些EF核心内部构件获得相应的
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);
    }
}
或者通过反射调用泛型
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(...)


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;
    }
}
公共静态类DbContextensions
{
公共静态IQueryable集(此DbContext _context,类型t)
{
return(IQueryable)_context.GetType().GetMethod(“Set”).MakeGenericMethod(t).Invoke(_context,null);
}
公共静态IQueryable集(此DbContext\u上下文,字符串表)
{
类型TableType=\u context.GetType().Assembly.GetExportedTypes().FirstOrDefault(t=>t.Name==table);
IQueryable ObjectContext=_context.Set(TableTypeDictionary[table]);
返回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\"");
IQueryable query=db.Set(“TableName”);
//根据下面的“查询”变量进行筛选。。。
列表结果=query.ToList();
//或者进一步使用动态Linq
IQueryable query=db.Set(“TableName”)。其中(“t=>t.TableFilter==\“MyFilter\”);

tenty是通用的,不是吗?看看这里,这也很有效。谢谢你的帮助,我真的很难用这个方法。我遇到了一个问题。我无法包含嵌套实体,因为没有包含()的定义。有没有办法解决这个问题?在我的例子中,IQueryable不包含Where的定义:(@mzain没有。所有LINQ扩展方法都是为
IQuerabley
定义的,而不是为
iquerable
定义的。因此,虽然答案显示了如何通过
Type
检索
DbSet
,但返回的结果不能直接使用。如果您事先知道类型
t
,最好使用
Set()
method.@Guerrilla这是如何工作的呢?您无法执行。没有泛型键入,Iqueriable上的Where.TableTypeDictionary?方法“Set”的重载不接受1个参数
IQueryable
没有
的实现。Where(string)
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\"");