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

发布于 2024-10-20 05:10:56 字数 903 浏览 0 评论 0原文

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

我们将以下内容与 contains 语句一起使用 -

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

它可以工作,但有两个问题。

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

  2. 如果没有人员姓名,则 Select 会引发异常。

对于常规查询来说并不困难,因为我们可以执行两个 from 语句,但 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;}
}

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;}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烈酒灼喉 2024-10-27 05:10:56

我们经过深思熟虑并做出了它,但这非常具有挑战性。以下是我们如何取得最终结果的各种方法。现在我们只需要重新思考我们的 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.与 Dynamic Linq 等效的 Lambda 语法

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

注释 - 您必须向 Dynamic Linq 库添加 Contains 方法。

编辑-或者仅使用选择...更简单...但它需要添加 Contains 方法,如上所述。

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

我们最初尝试过此操作,但遇到了可怕的“不存在适用的聚合方法 Contains”。错误。当我们试图让 SelectMany 工作时,我们用一种迂回的方式解决了这个问题......因此只是回到了 Select 方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文