簡體   English   中英

無法轉換func類型 <T,bool> 布爾

[英]can not convert type func<T,bool> to bool

我有以下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;

你可以不通過拉姆達到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<t_fault_stat_alt, bool>Func<t_fault_stat_alt, bool> -它不知道如何將其轉換為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"

原因是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);

為了仍然獲得相同的行為(Filter-Method),您必須將方法頭更改為如下所示:

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

有關更多信息,請查看例如: 為什么要使用Expression <Func <T >>而不是Func <T>? 或google C# Expression :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM