我有一个问题,我很难找到答案。
我有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我想&#34;生产&#34;是:
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有时候仍然会让我感到困惑。
如果您需要更多信息或者可以指出类似的问题(我发现了某种类似的情况,但无法正确使用它们),我将非常感激。
感谢您的时间。
答案 0 :(得分: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; }
}