无法将func <t,bool>类型转换为bool

时间:2018-10-15 07:27:49

标签: 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 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;

2 个答案:

答案 0 :(得分:2)

您不能使用查询语法将lambda传递到// before repeats, include first element printf("Opened Lockers: %d", openedLockers[0]); // repeat comma, space, element for (int i = 1; i < 5; i++) { printf(", %d", openedLockers[i]); } // after repeats printf(".\n"); 中-您需要改用方法语法。像

where

说明-

查询语法只是编译器为您提供的快捷方式。整个查询在编译时都使用LINQ方法调用重写。对于 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(); 子句,编译器需要一条语句,其结果为where-编译器将该语句转换为lambda。

您给了编译器lambda以(bool开头-它不知道如何将其转换为Func<t_fault_stat_alt, bool>

答案 1 :(得分:1)

即使该问题已被标记为正确,我也需要注意一些可能在评论中丢失的重要内容。

如果您使用 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"

原因是 EntityFramework 使用IQueriable来实际构建那些SQL查询。 然而,由于IQueryable也实现了IEnumerable,由于外观的原因,您可能陷入期望FuncExpression具有相同行为的陷阱。如果一个人自己检查方法,则区别会变得更加清晰:

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

要仍然获得相同的行为(过滤器方法),您必须将方法头更改为以下内容:

void MyWhere<T>(..., Expression<Func<T, bool>> cond)

有关此的更多信息,请查看例如: Why would you use Expression<Func<T>> rather than Func<T>? 或Google C# Expression:)

相关问题