Более простой способ выполнения запросов Entity Framework Core в LinqPad со встроенным драйвером Linq to SQL? - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу проанализировать запросы Entity Framework Core, , которые я скопировал из существующего кода в LinqPad, как

UserQuery this_context;
void Main()
{
    this_context = this;
    var validationResult = (

        from ProjectInfo pi in this_context.GetAll<ProjectInfo>()
        join GeneralInformation gi in this_context.GetAll<GeneralInformation>() 
                                   on pi.Id equals gi.Id into gpi
        from gps in gpi.DefaultIfEmpty()

        select new { ... }).ToList();
}

Я знаю, что Linqpad не поддерживает .NET Core, поэтому мне нужно немного его настроить - для этого я создал метод Extension следующим образом:

public static class Ext
{
    public static  IEnumerable GetAll<T>(this UserQuery uq)
    where T: new()
    {
        return GetAll(uq, new T());
    }

    private static  IEnumerable GetAll<T>(this UserQuery uq, T a)
    {
        switch (a)
        {
            case ProjectInfo v:
                return uq.ProjectInfo.Select(s => s);
            case GeneralInformation v:
                return uq.GeneralInformation.Select(s => s);

            // ... many more cases like the above 

            default: // unknown type
                throw new TypeAccessException($"Unsupported type {a.GetType().FullName}");
        }
    }

}

Перегруженная функция GetAll необходима для получения типа - она ​​просто создаетпустой новый объект и передает его так, чтобы оператор switch мог правильно вывести правильный тип и вернуть правильный запрос.

Это прекрасно работает, но это много усилий , чтобы поставитьв каждом отдельном типе в операторе switch.

Итак, мой вопрос:

Как этого можно достичь более разумным способом, то есть без необходимости указывать каждую отдельную сущностьтипа

1 Ответ

1 голос
/ 19 апреля 2019

Объект UserQuery LINQPad, кажется, имеет метод, который именно то, что вы хотите:

public static class Ext {
    public static IEnumerable GetAll<T>(this UserQuery uq) =>uq.GetTable(typeof(T));
}

Я считаю, что вы могли бы оставаться в безопасности с:

public static IQueryable<T> GetAll<T>(this UserQuery uq) => (IQueryable<T>)uq.GetTable(typeof(T));

Используя свой оригиналIEnumerable версия приводит к тому, что все таблицы загружаются в память одна за другой, а затем выполняется LINQ для объектов.Использование IQueryable<T> переводит запрос в SQL - это может быть нежелательно в тех случаях, когда LINQ to SQL и EF отличаются в переводе (без веской причины), но я мог видеть проблемы с конкретными возможностями EF (например, Include и DbFunctions, хотя я написал пустые Include методы расширения, чтобы скрыть это).

Если версия IQueryable не работает, версия ITable<> может:

public static ITable<T> GetAll<T>(this UserQuery uq) where T : class => (ITable<T>)uq.GetTable(typeof(T));
...