簡體   English   中英

自定義LINQ方法到存儲表達式中以供重用和稍后擴展

[英]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.

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