[英]Custom LINQ Method into a store expression for re-usability and scaling later
我正在嘗試創建可在LINQ Where子句中使用的可重用函數,設想它看起來像這樣:
using (var context = new AppDbContext())
{
_MyObject = context.MyObject.AsNoTracking()
//This works on MyObject (just FYI)
.WhereActive()
//Hoping for something like this (on a Child object)
.Where(o = IsActive(o.ChildObject))
//Or
.Where(o => o.MyChildObject.WhereActive())
;
}
return _MyObject;
這是我的BaseObject
,所有對象都具有IsActive
:
public class BaseObject
{
public BaseObject()
{
Oid = Guid.NewGuid();
IsActive = true;
}
[Key]
public Guid Oid { get; set; }
[ScaffoldColumn(false)]
public bool IsActive { get; set; }
}
在第一個示例中,我使用的是.WhereActive()
,效果很好:
public static class BaseObjectHelper
{
public static IQueryable<T> WhereActive<T>(this IQueryable<T> query)
where T : Entities.Base.BaseObject
{
return query.Where(b => b.IsActive);
}
}
我遇到的問題是我不知道如何創建可以進入Where
子句的方法或函數,如下所示:
。哪里(o = IsActive(o.MyChildObject))
或者:
.Where(o => o.MyChildObject.WhereActive())
類的例子:
public class MyObject : BaseObject
{
[Display(Name = "My Child Object")]
[Required]
public Guid? MyChildObjectID { get; set; }
[ForeignKey("MyChildObjectID")]
public virtual MyChildObject MyChildObject{ get; set; }
}
public class MyChildObject : BaseObject
{
}
請讓我知道我可以在哪里收集信息來解決我的問題,因為我嘗試了幾種方法但無法在LINQ中工作,所以不確定從哪里開始。
試過了,沒有用:
private bool IsActive(Menu menu)
{
if (menu.IsActive)
return true;
else
return false;
}
錯誤報告:
System.NotSupportedException:'LINQ to Entities無法識別方法'Boolean IsActive(xxxMyChildObject)'方法,並且該方法無法轉換為商店表達式。
我也想避免減慢查詢速度,我相信我回顧了一些需要遍歷列表以篩選出初始列表的示例。
我可以接受使用如下所示的內容,但是如果需要,可以在以后的表達式中添加條件:
.Where(o => o.MyChildObject.IsActive)
使用AsExandable()更新
_MenuItems = context.MyObject.AsNoTracking()
.Include(m => m.MyChildObject)
.WhereActive()
.AsExpandable().Where(a => IsActive.Invoke(a.MyChildObject))
.ToList();
Func<Menu, bool> IsActive { get; } = bo => bo.IsActive;
System.NotSupportedException:'LINQ to Entities無法識別方法'Boolean IsActive(xxxMyChildObject)'方法,並且該方法無法轉換為商店表達式。
而不是定義如下方法:
private bool IsActive(MyChildObject obj)
{
return obj.IsActive;
}
嘗試將其定義為返回表達式的屬性:
Expression<Func<ParentObject, bool>> IsActive { get; } = p => p.MyChildObject.IsActive;
然后,您可以在Linq中執行以下操作:
return query.Where(IsActive);
或者,您可以使用LinqKit( https://www.nuget.org/packages/LinqKit/ )。 然后,您可以像類字段一樣定義表達式:
readonly Expression<Func<MyChildObject, bool>> IsActive = ch => ch.IsActive;
並編寫如下的LINQ查詢:
return query.AsExpandable().Where(a => IsActive.Invoke(a.MyChildObject));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.