Dynamic Linq Search Expression on Navigation Properties

♀尐吖头ヾ 提交于 2020-01-05 04:34:09

问题


We are building dynamic search expressions using the Dynamic Linq library. We have run into an issue with how to construct a lamba expression using the dynamic linq library for navigation properties that have a one to many relationship.

We have the following that we are using with a contains statement-

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

It works but there are two problems.

  1. It of course only selects the FirstOrDefault() name. We want it to use all the names for each person.

  2. If there are no names for a person the Select throws an exception.

It is not that difficult with a regular query because we can do two from statements, but the lambda expression is more challenging.

Any recommendations would be appreciated.

EDIT- Additional code information...a non dynamic linq expression would look something like this.

 var results = persons.Where(p => p.Names.Select(n => n.FamilyName).FirstOrDefault().Contains("Smith")).ToList();

and the class looks like the following-

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:


We hashed it out and made it, but it was quite challenging. Below are the various methods on how we progressed to the final result. Now we just have to rethink how our SearchExpression class is built...but that is another story.

1. Equivalent Query Syntax

var results = from person in persons
from name in person.names
where name.FamilyName.Contains("Smith")
select person;

2. Equivalent Lambda Syntax

var results = persons.SelectMany(person => person.Names)
                     .Where(name => name.FamilyName.Contains("Smith"))
                     .Select(personName => personName.Person);

3. Equivalent Lambda Syntax with Dynamic Linq

var results = persons.AsQueryable().SelectMany("Names")
                     .Where("FamilyName.Contains(@0)", "Smith")
                     .Select("Person");

Notes - You will have to add a Contains method to the Dynamic Linq library.

EDIT - Alternatively use just a select...much more simple...but it require the Contains method addition as noted above.

var results = persons.AsQueryable().Where("Names.Select(FamilyName)
                                   .Contains(@0", "Smith)

We originally tried this, but ran into the dreaded 'No applicable aggregate method Contains exists.' error. I a round about way we resolved the problem when trying to get the SelectMany working...therefore just went back to the Select method.



来源:https://stackoverflow.com/questions/5177276/dynamic-linq-search-expression-on-navigation-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!