C# 无法转换类型func<;T、 布尔>;哄骗
我有以下linq,我想将不同的条件传递给where子句,但我得到了错误:C# 无法转换类型func<;T、 布尔>;哄骗,c#,linq,C#,Linq,我有以下linq,我想将不同的条件传递给where子句,但我得到了错误: var rslt = (from t in cr.faultStatAlt join v in cr.errorCatGroup on t.m_error_id equals v.m_error_id join h in cr.masterAlarm on t.m_inv_error_details equa
var rslt = (from t in cr.faultStatAlt
join v in cr.errorCatGroup
on t.m_error_id equals v.m_error_id
join h in cr.masterAlarm on t.m_inv_error_details equals h.pc_group_pattern into ps
from h in ps.DefaultIfEmpty()
join s in cr.MasterDataTurbine on t.m_turbine_id equals s.m_turbine_id
where (whereClause)
group t.error_duration by v.m_error_subgroup_name into k
select new faulttest
{
m_error_subgroup = k.Key,
error_duration = Math.Round(k.Sum() / 3600, 2)
}).ToString();
我要使其动态化的条件是:
Func<t_fault_stat_alt, bool> whereClause = t => t.m_date >= dt1 && t.m_date <= dt2 && t.m_grid_loss==true;
Func-whereClause=t=>t.m_-date>=dt1&&t.m_-date在查询语法中,不能将lambda传递到中,其中
——您需要改用方法语法。差不多
var fltr = (from t in cr.faultStatAlt
join v in cr.errorCatGroup
on t.m_error_id equals v.m_error_id
join h in cr.masterAlarm on t.m_inv_error_details equals h.pc_group_pattern into ps
from h in ps.DefaultIfEmpty()
join s in cr.MasterDataTurbine on t.m_turbine_id equals s.m_turbine_id)
.Where (whereClause);
var rslt = (from t in fltr
group t.error_duration by v.m_error_subgroup_name into k
select new faulttest
{
m_error_subgroup = k.Key,
error_duration = Math.Round(k.Sum() / 3600, 2)
}).ToString();
解释-
查询语法只是编译器为您提供的快捷方式。整个查询在编译时使用LINQ方法调用重写。对于where
子句,编译器需要一个计算结果为bool
的语句-编译器将该语句转换为lambda
您给了编译器一个lambda作为开始(Func
)-它不知道如何将其转换为bool
,您不能在查询语法中将lambda传递到where
-您需要改为使用方法语法。差不多
var fltr = (from t in cr.faultStatAlt
join v in cr.errorCatGroup
on t.m_error_id equals v.m_error_id
join h in cr.masterAlarm on t.m_inv_error_details equals h.pc_group_pattern into ps
from h in ps.DefaultIfEmpty()
join s in cr.MasterDataTurbine on t.m_turbine_id equals s.m_turbine_id)
.Where (whereClause);
var rslt = (from t in fltr
group t.error_duration by v.m_error_subgroup_name into k
select new faulttest
{
m_error_subgroup = k.Key,
error_duration = Math.Round(k.Sum() / 3600, 2)
}).ToString();
解释-
查询语法只是编译器为您提供的快捷方式。整个查询在编译时使用LINQ方法调用重写。对于where
子句,编译器需要一个计算结果为bool
的语句-编译器将该语句转换为lambda
你给了编译器一个lambda作为开始(Func
)-它不知道如何将它转换成bool
,即使问题已经被标记为正确,我需要注意一些重要的东西,可能会在注释中丢失
如果使用EntityFramework(或接受Expression
而不是Func
的任何其他内容),则需要使用不同的类型
给定以下代码,其中Tag是包含int字段Id
(+其对应列)的随机对象,cntxt是EntityFrameworkDBContext
,您将生成以下两个SQL查询:
Func<Data.Net.Tag, bool> cond = (tag) => tag.Id == 1;
var query = cntxt.Tags.Where(cond);
query.ToArray();
// SELECT "Extent1"."Id", "Extent1"."Name" FROM "public"."Tags" AS "Extent1"
query = cntxt.Tags.Where((tag) => tag.Id == 1);
query.ToArray();
// SELECT "Extent1"."Id", "Extent1"."Name" FROM "public"."Tags" AS "Extent1" WHERE 1 = "Extent1"."Id"
要仍然获得相同的行为(过滤方法),必须将方法头更改为以下内容:
void MyWhere<T>(..., Expression<Func<T, bool>> cond)
void MyWhere(…,表达式cond)
有关这方面的更多信息,请查看,例如:
或者谷歌C#Expression
:)尽管问题已经被标记为正确,但我需要注意一些重要的东西,它们可能会在评论中丢失
如果使用EntityFramework(或接受Expression
而不是Func
的任何其他内容),则需要使用不同的类型
给定以下代码,其中Tag是包含int字段Id
(+其对应列)的随机对象,cntxt是EntityFrameworkDBContext
,您将生成以下两个SQL查询:
Func<Data.Net.Tag, bool> cond = (tag) => tag.Id == 1;
var query = cntxt.Tags.Where(cond);
query.ToArray();
// SELECT "Extent1"."Id", "Extent1"."Name" FROM "public"."Tags" AS "Extent1"
query = cntxt.Tags.Where((tag) => tag.Id == 1);
query.ToArray();
// SELECT "Extent1"."Id", "Extent1"."Name" FROM "public"."Tags" AS "Extent1" WHERE 1 = "Extent1"."Id"
要仍然获得相同的行为(过滤方法),必须将方法头更改为以下内容:
void MyWhere<T>(..., Expression<Func<T, bool>> cond)
void MyWhere(…,表达式cond)
有关这方面的更多信息,请查看,例如:
或者谷歌C#Expression
:)我想你必须将部分/所有这些从查询语法转换为方法语法。@Fildor-错误列在问题的标题中。@just.other.programmer哈哈,对了。。。我去喝杯咖啡……你在调用你的函数吗?尝试whereClause.Invoke(parameter)
或只是whereClause(parameter)
您可以在Query
格式Where子句中传递Func
bool逻辑,类似于where t.m_date>=dt1&&t.m_date,我怀疑您必须将部分/所有这些从查询语法转换为方法语法。@Fildor-错误列在问题的标题中。@just.other.programmer哈哈,对了。。。我去喝杯咖啡……你在调用你的函数吗?试试whereClause.Invoke(parameter)
或者干脆whereClause(parameter)
你可以在Query
format Where子句中传递Func
bool逻辑,比如Where t.m_date>=dt1&&t.m_date你当然可以在查询语法中使用它,您只需使用正确的参数调用它:where子句(t)
您可能需要注意我添加的答案,以警告人们在不合适的时候使用它(例如使用EntityFramework)。哦。。。此外,还可以将Func
传递到LINQ,其中。。但是你需要实际调用它才能从t中工作。。。where子句(t).
@pinkfloydx33两者之间有一个关键的区别-对于where子句(t)
,编译器将编写一个MethodCallExpression来调用带有参数expression t的where子句(t)
。使用.Where(Where子句)
,您只得到谓词。这是至关重要的b/c许多查询提供程序(如LINQ to SQL和LINQ to EF)不支持MethodCallExpression。@X39只有在向查询语法添加方法调用时才会出现此问题。您当然可以在查询语法中使用它,只需使用正确的参数调用它:where子句(t)
您可能需要注意我添加的答案,以警告人们在不合适的情况下使用此选项(例如使用EntityFramework)。哦。。。此外,还可以将Func
传递到LINQ,其中。。但是你需要实际调用它才能从t中工作。。。where子句(t).
@pinkfloydx33两者之间有一个关键的区别-对于where子句(t)
,编译器将编写一个MethodCallExpression来调用带有参数expression t的where子句(t)
。使用.Where(Where子句)
,您只得到谓词。这是非常关键的b/c许多查询提供程序(如LINQ to SQL和LINQ to EF)不支持MethodCallExpression。@X39您只有在向查询语法添加方法调用时才会遇到这个问题。如果您可以提供一个Func
,其中需要表达式
,这将是一个编译错误。没有理由用Func替换表达式,只是两者都有simil