我正在尝试在 ArticleTypeId 上加入 TableA 和 TableB 并基本上从 Table1 中返回所有内容,从 Table2 中返回 TypeName
在你定义了你的类之后,你的查询就很容易了。最简单的方法是使用虚拟属性。
使用虚拟属性
要求给我所有文章的 ID 和名称,每篇文章都有它的 TypeName。
using (var wareHouse = new MyWareHouse(...))
{
var requestedArticles = wareHouse.Articles.Select(article => new
{
// Select only the Article Properties that you plan to use
Id = article.Id,
Name = article.Name,
TypeName = article.ArticleType.TypeName,
});
// Process the requested Articles before disposing the wareHouse
}
换句话说:从 Articles 表中的每篇文章中获取 Id、Name 以及它拥有的唯一一个 TypeName。
实体框架知道 Articles 和 ArticleTypes 之间的关系。因为您使用虚拟属性Article.ArticleType,它知道要执行哪个连接。
使用虚拟属性,您还可以获得每个 ArticleType 以及具有此 ArticleTypes 的所有文章
var constructionArticles = wareHouse.ArticleTypes
.Where(articleType => articleType.TypeName == "construction")
.Select(articleType => new
{
Id = articleType.Id,
TypeName = articleType.TypeName,
// fetch all articles that have this TypeName
Articles = articleType.Articles.Select(article => new
{
Id = article.Id,
Name = article.Name,
// no need to fetch the foreign key, you already got this value
// ArticleTypeId = article.ArticleTypeId,
})
.ToList(),
})
.ToList();
实体框架知道这种关系,并会为你做正确的(组)加入。
您是否注意到使用虚拟属性的感觉是多么自然?
自己加入
有些人不想使用虚拟属性,他们更喜欢自己做(Group-)joins。
使用具有参数 resultSelector 的方法 Join 的重载,因此您可以指定所需的结果。
// Join Articles with ArticleTypes
var requestedArticles = wareHouse.Articles.Join(wareHouse.ArticleTypes,
// from every Article take the foreign key
article => articleTypeId,
// from every ArticleType take the primary key
articleType => articleType.Id,
// parameter resultSelector:
// take each article and its one and only matching ArticleType to make one new
(article, articleType) => new
{
Id = article.Id,
Name = article.Name
TypeName = articleType.TypeName,
});
如果你有一对多的关系,比如学校和他们的学生,客户和他们的订单,或者 ArticleTypes 和他们的文章,使用 GroupJoin 并从“一”端开始。如果你想要学生,他就读的学校的每个学生,使用加入,并从“多”端开始。
var schoolsWithTheirStudents = dbContext.Schools
.Where(school => school.City == ...) // if you don't want all Schools
.GroupJoin(dbContext.Students,
// from every School take the primary key
school => school.Id,
// from every Student take the foreign key to the School he attends
student => student.SchoolId,
// resultSelector: take each Schools with its matching Students to make one ned
(school, studentsWhoAttendThisSchool) => new
{
// Select only the School properties that you plan to use:
Id = school.Id,
Name = school.Name,
Address = school.Address,
...
// studentsWhoAttendThisSchool is a queryable sequence,
// so you can use LINQ on it:
Students = studentsWhoAttendThisSchool.Select(student => new
{
Id = student.Id,
Name = student.Name,
...
})
.ToList(),
});
})