如何将给定的 lambda 查询转换为 IQueryable
How to convert given lambda query to IQueryable
我准备了这个 Linq-to-SQL 查询,它需要作为 IQueryable
执行,但它失败了。
当我通过调用 ToList
转换 filteredResult
时,效果很好,但我需要将 filteredResult
用作 IQueryable
并获得 select 结果以下。但是我得到一个错误
A lambda expression with a statement body cannot be converted to an expression tree
通过了下面的 link,但是,下面的查询如何转换为 IQueryable
。根据 link,我是否需要编写 Func<object,object>
或任何转换查询的示例真的很有帮助。
"A lambda expression with a statement body cannot be converted to an expression tree"
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
};
});
单独的函数无济于事。无论哪种情况,系统都无法计算出如何从复杂的 C# 代码生成 SQL。
试试这个:
// 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
});
我认为这应该可行。让我知道。
编辑:
奇怪的是,虽然不允许使用空传播运算符,但旧的条件 if 是允许的,所以请尝试:
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
});
我准备了这个 Linq-to-SQL 查询,它需要作为 IQueryable
执行,但它失败了。
当我通过调用 ToList
转换 filteredResult
时,效果很好,但我需要将 filteredResult
用作 IQueryable
并获得 select 结果以下。但是我得到一个错误
A lambda expression with a statement body cannot be converted to an expression tree
通过了下面的 link,但是,下面的查询如何转换为 IQueryable
。根据 link,我是否需要编写 Func<object,object>
或任何转换查询的示例真的很有帮助。
"A lambda expression with a statement body cannot be converted to an expression tree"
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
};
});
单独的函数无济于事。无论哪种情况,系统都无法计算出如何从复杂的 C# 代码生成 SQL。
试试这个:
// 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
});
我认为这应该可行。让我知道。
编辑:
奇怪的是,虽然不允许使用空传播运算符,但旧的条件 if 是允许的,所以请尝试:
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
});