Я использую EF Core 3.0 в своем проекте, и теперь я пытаюсь реализовать свое собственное обобщение.
public class DatabaseQueryObject
{
public string DbName { get; set; }
public ICollection<string> Tables { get; set; }
public Type RequestedDataType { get; set; }
public string? Filter { get; set; }
public object[] FilterParams { get; set; }
public ICollection<Guid> Ids { get; set; }
}
public async Task<List<dynamic>> GetCustomTableElemById(DatabaseQueryObject request)
{
var query = dbContext.Query(request.DbName);
var requestedQuery = query.Where("e => request.Ids.Contains(e.Id)");
var filteredQuery = request.Filter != null ? requestedQuery.Where(request.Filter, request.FilterParams) : requestedQuery;
var executedQuery = await filteredQuery.ToDynamicListAsync();
return resultObjectCreator.Create(result: request.Ids.Count > 0 ? executedQuery : executedQuery.FirstOrDefault() as object);
}
Здесь dbContext
- тот же контекст EF Core, полученный из DbContext.
public static class DbContextExtensions
{
public static IQueryable Query(this DbContext context, string entityName)//, [Optional]T dataType)
{
var entityType = context.Model.GetEntityTypes().FirstOrDefault(f => f.ShortName() == entityName);
var result = (IQueryable)context.Query(entityType.ClrType);//context.Model.FindEntityType(entityName).ClrType);
return result;
}
static readonly MethodInfo SetMethod = typeof(DbContext).GetMethod(nameof(DbContext.Set));
public static IQueryable Query(this DbContext context, [Optional] Type entityType)
{
return SetMethod.MakeGenericMethod(entityType).Invoke(context, null) as IQueryable;
}
}
Но этот код возвращает IQueryable
и это никак не может вернуть IQueryable<T>
, который должен использовать его с Include()
(если я хочу включить подтаблицы). Также у меня есть ошибка времени выполнения в кодовой части var requestedQuery = query.Where("e => request.Ids.Contains(e.Id)");
, потому что request.Ids
не является частью DbSet<SameClass>
, который определен в dbContext
.
Итак, у меня есть несколько вопросов.
- Как сказать EF Core, что
request.Ids
- это внешняя коллекция? - Как реализовать
IQueryable<T>
вместо IQueryable
? - Как реализовать
Include()
метод через IQueryable
? - Как отказаться от
dynamic
использования и использовать конкретный тип в этом коде? - Какова производительность
System.Linq.Dynamics
? Это хуже?