我們正在使用Dynamic Linq庫構建動態搜索表達式。關於如何使用動態linq庫構造具有一對多關係的導航屬性的lamba表達式,我們遇到了一個問題。
我們將以下內容與包含語句一起使用-
Person.Names.Select(FamilyName).FirstOrDefault()
它可以工作,但是有兩個問題。
當然,它僅選擇FirstOrDefault()名稱。我們希望它使用每個人的所有名稱。
如果沒有人的姓名,則Select會引發異常。
常規查詢並不困難,因為我們可以從語句中進行兩個操作,但是lambda表達式更具挑戰性。
任何建議,將不勝感激。
編輯-其他代碼信息...一個非動態linq表達式看起來像這樣。
var results = persons.Where(p => p.Names.Select(n => n.FamilyName).FirstOrDefault().Contains("Smith")).ToList();
並且該類如下所示-
public class Person
{
public bool IsActive { get; set;}
public virtual ICollection<Name> Names {get; set;}
}
public class Name
{
public string GivenName { get; set; }
public string FamilyName { get; set; }
public virtual Person Person { get; set;}
}
我們對其進行了哈希處理,但確實具有挑戰性。以下是關於如何逐步達到最終結果的各種方法。現在我們只需要重新考慮我們的SearchExpression類是如何構建的……但這是另一回事了。
1.等效查詢語法
var results = from person in persons
from name in person.names
where name.FamilyName.Contains("Smith")
select person;
2.等效的Lambda語法
var results = persons.SelectMany(person => person.Names)
.Where(name => name.FamilyName.Contains("Smith"))
.Select(personName => personName.Person);
3.具有動態Linq的等效Lambda語法
var results = persons.AsQueryable().SelectMany("Names")
.Where("FamilyName.Contains(@0)", "Smith")
.Select("Person");
注意 -您必須將Contains方法添加到Dynamic Linq庫。
編輯-或者僅使用select ...更簡單...但是它需要如上所述的Contains方法添加。
var results = persons.AsQueryable().Where("Names.Select(FamilyName)
.Contains(@0", "Smith)
我們最初嘗試過此方法,但遇到了可怕的“不存在任何適用的聚合方法”。錯誤。在嘗試使SelectMany正常工作時,我解決了問題的方法。因此,我們回到了Select方法。