Как преобразовать данный лямбда-запрос в IQueryable - PullRequest
0 голосов
/ 22 марта 2020

Я подготовил этот запрос Linq-to-SQL, и он должен быть выполнен как IQueryable, но он не работает.

Когда я конвертирую filteredResult, вызывая ToList, тогда он работает хорошо но мне нужно использовать filteredResult как IQueryable и получить результат выбора, как показано ниже. Но я получаю сообщение об ошибке

Лямбда-выражение с телом оператора не может быть преобразовано в дерево выражений

По ссылке ниже, но как может быть приведен запрос ниже преобразуется в IQueryable. Что касается ссылки, мне нужно написать Func<object,object> или любой пример для преобразования запроса будет действительно полезным.

"Лямбда-выражение с телом оператора не может быть преобразовано в дерево выражений"

var result = filteredResult.Select(g => {
    var type1 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ1);
    var type2 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ2);

return new AutoDetailDto
    {
        MilestoneId = g.Key.MilestoneId,
        MilestoneName = g.Key.MilestoneName,
        PGrade = type1?.GDR,
        PGradeChange = type1?.HighestGDR
        QGrade = type2.GDR,
        QGradeChange = type2?.HighestGDR    
    };
});

1 Ответ

1 голос
/ 22 марта 2020

Отдельная функция не поможет. В любом случае система не может понять, как сгенерировать SQL из сложного C# кода.

Попробуйте:

// This is converted to SQl because the lambda, though compe, is a single statement
var dataResult = filteredResult.Select(g => new {
    type1 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ1),
    type2 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ2),
    MilestoneId  = g.Key.MilestoneId,
    MilestoneName = g.Key.MilestoneName
}).ToArray(); // ToArray() forces execution of the query  

// This select is done entirely in memory
var result = dataResult.Select (e =>
       new AutoDetailDto
       {
           MilestoneId = e.MilestoneId,
           MilestoneName = e.MilestoneName,
           PGrade = e.type1?.GDR,
           PGradeChange = e.type1?.HighestGDR
           QGrade = e.type2.GDR,
           QGradeChange = e.type2?.HighestGDR    
       });

Я думаю, это должно работать. Дайте мне знать.

РЕДАКТИРОВАТЬ:

Странно то, что, хотя нулевой распространяющий оператор не допускается, старый условный, если есть, так что попробуйте:

var dataResult = filteredResult.Select(g => new {
        type1 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ1),
        type2 = g.FirstOrDefault(x => x.CategoryId == (int)CategoryEnum.Typ2),
        MilestoneId  = g.Key.MilestoneId,
        MilestoneName = g.Key.MilestoneName
    }); // No forcing of execution here

var result = dataResult.Select (e =>
       new AutoDetailDto
       {
           MilestoneId = e.MilestoneId,
           MilestoneName = e.MilestoneName,
           PGrade = e.type1 == null ? null : e.type1.GDR,
           PGradeChange = e.type1 == null ? null :e.type1.HighestGDR
           QGrade = e.type2 == null ? null : e.type2.GDR,
           QGradeChange = e.type2 == null ? null : e.type2.HighestGDR    
       });
...