动态Linq搜索表达式的导航属性

时间:2011-03-03 06:04:57

标签: linq dynamic-linq

我们正在使用Dynamic Linq库构建动态搜索表达式。我们遇到了如何使用动态linq库为具有一对多关系的导航属性构建lamba表达式的问题。

我们正在使用包含语句的< - p>

 Person.Names.Select(FamilyName).FirstOrDefault()

它有效,但有两个问题。

  1. 它当然只选择FirstOrDefault()名称。我们希望它使用每个人的所有名字。

  2. 如果没有人的名字,则Select会抛出异常。

  3. 使用常规查询并不困难,因为我们可以从语句中执行两次操作,但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;}
    }
    

1 个答案:

答案 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方法。