簡體   English   中英

如何在linq where子句中使用函數的返回值?

[英]How to use the return value of a function in a linq where clause?

我正在嘗試針對EF實體類型(人)創建常規搜索查詢。 通常,搜索采用字符串,將其用逗號分隔,然后搜索其各種屬性包含所有關鍵字的人員。

我有一個名為getProperties(Person p)的函數,該函數接受一個實體(按實體類型重寫),並返回由各種相關屬性組成的字符串,這些字符串與一個定界符結合在一起,例如:

John~Doe~Team A~Full Time

如果用戶搜索與上述扁平實體相對應的“ Team A,Full”人員,則應返回……但是,如果輸入“ John,Smith”,則不應返回。

我認為以下內容看起來不錯,但它行不通...

public IEnumerable<Person> SearchPeople(string searchString)
{
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim()))
        return base._objectSet.ToList();

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray();

    return (from    person 
            in      base._objectSet 
            let     t = (getProperties(person)) 
            where   SearchWords.All(word => t.Contains(word)) 
            select  person).ToList();
}

而getProperties函數是:

public static string getProperties(Person p)
{
    string[] values = { p.Surname, p.GivenName, p.Team, p.Status };
    return values.Aggregate((x, y) => String.IsNullOrEmpty(y) ? x : string.Concat(x, "~", y));
}

有人看到我要去哪里了嗎?

編輯

沒有引發異常,但是當我單步執行代碼時,當我到達linq時,它會進入托管查詢的unitofwork的dispose方法。 很奇怪。

如果我對其進行更改,使其針對硬編碼的字符串進行搜索,則它將按預期工作:

var test = (from    person 
            in      base._objectSet 
            where   SearchWords.All(word => "John~Doe~Team A~Full Time".Contains(word))
            select person).ToList();

好吧,它的工作原理是它與我期望的查詢匹配,但是由於它是靜態的,它返回每個人的記錄(非常像具有where(true)= P)

編輯第二個

甚至更奇怪的是,如果我將結果存儲到var中,然后在返回值上返回帶有斷點的var,則執行永遠不會遇到斷點...此linq就像一個黑洞...我可以進入它,但是它從不讓我回到我的SearchPeople方法...它只是處理上下文而忘記了它。

編輯第三個

如果我沒有立即調用ToString()並在調試器中查看linq表達式,它會顯示“ Linq to Entities無法識別方法getProperties(Person)”看起來它在無聲地阻塞了我的方法……使用我的方法而不會被linq扼殺嗎?

您要返回列表? 嘗試將返回類型設為List或將.ToList()更改為AsEnumerable()

public List<Person> SearchPeople(string searchString)
{
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim()))
        return base._objectSet.ToList();

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray();

    return (from    person 
            in      base._objectSet 
            let     t = (getProperties(person)) 
            where   SearchWords.All(word => t.Contains(word)) 
            select  person).ToList();
}

好吧,在發現linq 2 entites不喜歡方法(因為不知道如何將其轉換為sql)之后,我重寫了linq是一種非常繁瑣但有效的方式:

var people = from    p
             in      base._objectSet
             where   SearchWords.All(p.GivenName.Contains(word) || p.Surname.Contains(word) || p.(???).Contains(word) || etc.)
                    select p;

煩人,但是你去了。

暫無
暫無

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

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