动态访问EF Core 2.0中的表

时间:2017-12-31 10:48:16

标签: c# linq asp.net-core entity-framework-core

我使用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(...)

我该怎么做?

2 个答案:

答案 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\"");