我们正在使用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方法。