Создать обобщение запросов - PullRequest
0 голосов
/ 09 ноября 2019

Я использую 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.

Итак, у меня есть несколько вопросов.

  1. Как сказать EF Core, что request.Ids - это внешняя коллекция?
  2. Как реализовать IQueryable<T> вместо IQueryable?
  3. Как реализовать Include() метод через IQueryable?
  4. Как отказаться от dynamic использования и использовать конкретный тип в этом коде?
  5. Какова производительность System.Linq.Dynamics? Это хуже?
...