_System.Linq.Dynamic.Core
_を使用して、EFのクエリにラムダ式を動的に追加しています。
また、名前でテーブルを選択できるようにしたいです。私はこの答えを見つけました:
https://stackoverflow.com/a/28101268/657477
ただし、asp.net core 2.0では機能しません。 DbSet
は使用できません。エラーメッセージに記載されている_DbSet<TEntity>
_を使用する必要があります。
db.GetTable("Namespace.MyTable").Where(...)
ができるようにしたい
これどうやってするの?
最初に、名前からエンティティのタイプを取得する必要があります(タイプがある場合は、それを直接使用します)。そのためにリフレクションを使用できますが、おそらくEF Coreの正しい方法は FindEntityType
メソッドを使用することです。
型を取得したら、対応する_DbSet<T>
_を取得する方法が問題になります。現在、EF CoreはEF6に似た非ジェネリックSet(Type)
メソッドを提供していません。これは主に非ジェネリックDbSet
クラスがないためです。ただし、EF Core内部を使用することで、対応する_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(...)
_
または
_db.Query(typeof(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;
}
}
}
使用法:
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\"");