动态访问EF Core 2.0中的表

Gue*_*lla 12 c# linq entity-framework-core asp.net-core

System.Linq.Dynamic.Core用来动态地将lambda表达式添加到EF中的查询中.

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

/sf/answers/1967088791/

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

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

我怎样才能做到这一点?

Iva*_*oev 20

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

一旦你有了类型,问题是如何得到相应的DbSet<T>.EF Core目前不提供Set(Type)类似于EF6的非泛型方法,主要是因为没有非泛型DbSet类.但是,你仍然可以得到相应DbSet<T>IQueryable通过或者使用一些EF核心内部:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

db.Query("Namespace.MyTable").Where(...)
Run Code Online (Sandbox Code Playgroud)

要么

db.Query(typeof(MyTable)).Where(...)
Run Code Online (Sandbox Code Playgroud)

  • 就我而言,IQueryable不包含Where的定义:( (2认同)
  • @Guerrilla 这效果如何?如果没有通用类型,则无法在 Iqueriable 上执行 .Where 。 (2认同)

jdm*_*eon 6

EF Core 不再具有非泛型Set方法,但是此扩展类可以使用动态 linq 根据字符串轻松查询表。考虑TableTypeDictionary是一个Dictionary<string, Type>映射 DbSet 类型及其类型名称。

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;
        //One way to get the Type
        tableType = _context.GetType().Assembly.GetExportedTypes().FirstOrDefault(t => t.Name == table);
        //The Second way, get from the dictionary which we've initialized at startup
        tableType = TableTypeDictionary[table];
        //The third way, works only if 'table' is an 'assembly qualified type name'
        tableType = Type.GetType(table);

        IQueryable<Object> objectContext = _context.Set(tableType);
        return objectContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

IQueryable<Object> query = db.Set("TableName");
//or if you're using the third way:
query = db.Set(MyTable.GetType().AssemblyQualifiedName);

// 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\"");
Run Code Online (Sandbox Code Playgroud)

  • 表类型字典? (8认同)
  • 方法“Set”没有重载需要 1 个参数 (2认同)