Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法转换类型func<;T、 布尔>;哄骗_C#_Linq - Fatal编程技术网

C# 无法转换类型func<;T、 布尔>;哄骗

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

我有以下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 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是EntityFramework
DBContext
,您将生成以下两个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是EntityFramework
DBContext
,您将生成以下两个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