First you need to get the type of the entity from the name (in case you have the type, just use it directly). You can use reflection for that, but probably the correct way for EF Core is to use FindEntityType
method.
Once you have the type, the problem is how to get the corresponding DbSet<T>
. EF Core currently does not provide non generic Set(Type)
method similar to EF6, mainly because there is no non generic DbSet
class. But you can still get the corresponding DbSet<T>
as IQueryable
by either using some EF Core internals:
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);
}
}
or invoking the generic Set<T>
method via reflection:
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);
}
}
In both cases you can use something like this:
db.Query("Namespace.MyTable").Where(...)
or
db.Query(typeof(MyTable)).Where(...)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…