J'utilise System.Linq.Dynamic.Core
Pour ajouter dynamiquement des expressions lambda aux requêtes dans EF.
Je souhaite également pouvoir sélectionner le tableau par son nom. J'ai trouvé cette réponse:
https://stackoverflow.com/a/28101268/657477
Mais cela ne fonctionne pas dans asp.net core 2.0. Je ne peux pas utiliser DbSet
Je dois utiliser DbSet<TEntity>
Comme indiqué dans le message d'erreur.
Je veux pouvoir faire db.GetTable("Namespace.MyTable").Where(...)
Comment puis-je faire ceci?
Vous devez d'abord obtenir le type de l'entité à partir du nom (au cas où vous auriez le type, utilisez-le directement). Vous pouvez utiliser la réflexion pour cela, mais probablement la bonne façon pour EF Core est d'utiliser la méthode FindEntityType
.
Une fois que vous avez le type, le problème est de savoir comment obtenir le DbSet<T>
Correspondant. EF Core ne fournit actuellement pas de méthode Set(Type)
non générique similaire à EF6, principalement parce qu'il n'y a pas de classe DbSet
non générique. Mais vous pouvez toujours obtenir le DbSet<T>
Correspondant en tant que IQueryable
en utilisant des internes EF Core:
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);
}
}
ou en invoquant la méthode générique Set<T>
via la réflexion:
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);
}
}
Dans les deux cas, vous pouvez utiliser quelque chose comme ceci:
db.Query("Namespace.MyTable").Where(...)
ou
db.Query(typeof(MyTable)).Where(...)
EF Core n'a plus de méthode .set non générique, mais cette classe d'extension facilite l'interrogation de votre table en fonction d'une chaîne à l'aide de linq dynamique
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;
}
}
}
usage:
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\"");