繁体   English   中英

如何使用单个SQL生成的查询在EFCore中选择模拟多对多属性

[英]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> categoryNamesList<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)解决方案都将在应用选择之前从服务器加载所有数据。

是否有满足以下条件的查询:

  • 仅生成1条SQL查询
  • 不会加载整个链接实体和/或整个导航属性2个“跳”。
  • 仅返回CategoryNames的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM