[英]How to select properties of simulated many-to-many in EFCore with single SQL generated query
EFCore在不创建链接实体的情况下不支持多对多关系。 我需要从一对多关系的“另一端”有效地选择属性的子集。
我发誓这已经有了答案,但是还没有找到答案。
使用这些模型:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public Author Author { get; set; }
public ICollection<BookCategory> BookCategories { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string ExtraProperties {get; set; }
public ICollection<BookCategory> BookCategories { get; set; }
}
public class BookCategory
{
public int BookId { get; set; }
public Book Book { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
这个问题是类似但不同的问题的扩展,题为“ 从实体框架核心中的包含属性中选择特定属性 ”
我正在寻找一个查询,该查询返回Book List<string> categoryNames
的List<string> categoryNames
。
使用“投影”的此嵌套选择将导致多个SQL查询:
var result= await _ctx.Books
.Where(x => x.BookId == id)
.Select(x => x.BookCategorys
.Select(y => y.Category.CategoryName )
.ToList())
.FirstOrDefaultAsync();
任何具有.Include(x => x.BookCategory).ThenInclude(x => Category)
解决方案都将在应用选择之前从服务器加载所有数据。
是否有满足以下条件的查询:
List<string>
。 我从这个Entity Framework Core推断出, 对于一对多关系会生成两个选择查询 ,这是不可能的。
通常,您无法控制生成的SQL以及ORM执行多少个SQL查询。 并且已知在撰写本文时(2.0.2版),当查询包含集合投影时,EF Core会生成N + 1个查询。 此问题在下一个2.1版本中已修复 ,但仍将生成并执行至少2个查询。
但是每条规则都有例外。 既然你只想返回一个相关的电突出,你可以简单地使用SelectMany
代替原来的Select
+ FirstOrDefault
构建。 这些等效于这种情况,并且EF Core不够聪明,无法以与后者相同的方式对待后者。 算上需要考虑多少其他情况,这是可以理解的。 好处是,以这种方式重写LINQ查询会产生所需的单个SQL查询转换:
var result = await _ctx.Books
.Where(x => x.BookId == id)
.SelectMany(x => x.BookCategorys
.Select(y => y.Category.CategoryName))
.ToListAsync();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.