EF Core选择由相关实体过滤的一个实体

问题描述 投票:2回答:1

我有一个问题,我很难找到答案。

我有3个实体类,其关系类似于(简化):

class Article {
 public int id
 public string Name
 public int ArticleStandard Id
 public int CompanyId
 public ArticleStandard ArticleStandardNavigation
 public Company CompanyNavigation
}
class ArticleStandard {
 public int id
 public ICollection<Article> Articles
}
class Company {
 public in id
 public ICollection<Article> Articles
}

所以关系是1公司可以有很多文章,1标准文章可以有很多文章。它们都在DBContext中设置为DBSets。鉴于是ArticleStandard的Id。我现在想通过文章实体获得所有拥有此标准文章的公司。我想“生产”的TSQL是:

  select c.* from Company c
  inner join Article a on c.ID = a.CompanyId
  inner join ArticleStandard on a.ArticleStandard = arts.id
  Where arts.Id = 1

这给出了我想要的结果。

我尝试了很多,我不想发布我的所有试验来解决这个问题,这可以让它与Include和ThenInclude一起工作。但我不想得到所有文章和文章标准。如果我只选择公司,则忽略包含:https://docs.microsoft.com/en-us/ef/core/querying/related-data#ignored-includes

var vtp = context.Company.Include(a => a.Article).ThenInclude(ars => ars.ArticleStandardNavigation).ToList();

在这里,我也很难在包含的实体上使用where子句。我在这里读到了这个问题:How to add where clause to ThenInclude

但我无法让它真正起作用,特别是只检索公司而不是其他实体。

我知道我可以加载所有并且只是把公司拿出来。那会有用。但我希望减少发送的数据量,并将查询保持为一个。

任何提示?我仍然对EF Core缺乏经验,LinQ有时候仍然会让我感到困惑。

如果你需要更多的信息或者可以指出我遇到类似的问题(我发现了某种类似的情况,但是无法正确使用它们)我会非常感激。

感谢您的时间。

c# linq include entity-framework-core
1个回答
6
投票

好吧,忘记SQL和连接。在针对LINQ查询的EF(Core)中,您可以使用导航属性来访问相关数据。在查询的上下文中,实体表示数据库表记录和导航 - 连接和相关表记录。

对于参考导航属性,您使用以下简单条件:

Where(entity => entity.Reference.SomeProperty == someValue)

对于集合导航属性,通常Any具有所需的标准,例如:

Where(entity => entity.Collection.Any(related => related.SomeProperty == someValue))

换句话说,我希望记录中至少有一个具有此值的相关记录。

将上述规则应用于您的模型,等效查询将如下所示:

var query = db.Companies
    .Where(c => c.Articles.Any(a => a.ArticleStandardNavigation.id == 1));

生成的SQL很可能与您手工编写的SQL不同(通常我们无法控制ORM的SQL生成),但结果应该是。

顺便说一句,没有必要将Navigation附加到导航属性名称。默认(更直观)的约定是使用类名,例如

public class Article
{
    // ...
    public ArticleStandard ArticleStandard { get; set; }
    public Company Company { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.