![](/img/trans.png)
[英]Convert type in Expression<Func<T1, bool>> to Expression<Func<T2, bool>> (LINQ to SQL)
[英]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
,因此由於外觀的原因,您可能陷入期望Func
和Expression
具有相同行為的陷阱。 如果實際上自己檢查方法,則區別會變得更加清晰:
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.