Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用单个SQL生成的查询选择EFCore中模拟多对多的属性_C#_Entity Framework Core - Fatal编程技术网

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

C# 如何使用单个SQL生成的查询选择EFCore中模拟多对多的属性,c#,entity-framework-core,C#,Entity Framework Core,如果不创建链接实体,EFCore不支持多对多关系。我需要从一对多对一关系的“另一端”高效地选择属性子集 我发誓这已经有答案了,但还没找到 对于这些型号: public class Book { public int BookId { get; set; } public string Title { get; set; } public Author Author { get; set; } public ICollection<BookCategory&g

如果不创建链接实体,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; }
}
任何具有.Includex=>x.BookCategory.ThenCludex=>Category的解决方案都将在应用select之前从服务器加载所有数据

是否有符合以下条件的查询

仅生成1个SQL查询 不会在中加载整个链接实体和/或整个导航属性2“跃点”。 仅返回CategoryNames的列表。
我由此推断,这是不可能的。

一般来说,您无法控制生成的SQL以及ORM执行多少SQL查询。在编写版本2.0.2时,已知EF Core在查询包含集合投影时会生成N+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();

切向上,模拟的多对多采用一对多对一的形式,而不是多对一对多的形式。在一对多的情况下,多数人认为FK是一对一。因此,交叉表是多对二,因为它包含两个FKs@Flater,你完全正确。我得花点时间考虑一下。将更新标题和正文,但不确定标题最具广泛吸引力的最佳术语。
var result = await _ctx.Books
    .Where(x => x.BookId == id)
    .SelectMany(x => x.BookCategorys
        .Select(y => y.Category.CategoryName))
    .ToListAsync();