我们正在使用Dynamic Linq库构建动态搜索表达式。我们遇到了如何使用动态linq库为具有一对多关系的导航属性构建lamba表达式的问题。
我们正在使用包含语句的< - p>
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;}
}
答案 0 :(得分:2)
我们把它搞砸了,但是它非常具有挑战性。以下是我们如何进展到最终结果的各种方法。现在我们只需要重新思考我们的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库。
编辑 - 或者只使用一个选择...更简单...但它需要添加Contains方法,如上所述。
var results = persons.AsQueryable().Where("Names.Select(FamilyName)
.Contains(@0", "Smith)
我们最初尝试过这个,但遇到了可怕的“没有适用的聚合方法包含存在”。错误。我试图让SelectMany工作时我们解决了这个问题......因此我回到了Select方法。