您如何使用Entity Framework Core 2.1查询多对多关系?

时间:2018-10-19 11:59:31

标签: entity-framework asp.net-core ef-core-2.0 ef-core-2.1

我正在尝试使用EF Core(代码优先)从多对多关系中选择数据,并遇到以下错误:

  

未处理的异常:System.ArgumentException:必须是可还原的节点

我认为我没有做任何特别奇怪的事情,并且我可以使用LinqPad中的LinqToSQL来愉快地运行有问题的查询。希望有人可以指出我要去哪里错了?

我已经在控制台应用程序中创建了一个最小的(人为的)复制品,可以在here中找到它。基本上,我已将连接表建模为follows

public class Foo
{
    [Key]
    public int Id { get; set; }

    public ICollection<FooBar> FooBars { get; set; } = new List<FooBar>();
}

public class Bar
{
    [Key]
    public int Id { get; set; }

    public string Value { get; set; }

    public ICollection<FooBar> FooBars { get; set; } = new List<FooBar>();
}

public class FooBar
{
    [Required]
    public int FooId { get; set; }

    [ForeignKey(nameof(FooId))]
    public Foo Foo { get; set; }

    [Required]
    public int BarId { get; set; }

    [ForeignKey(nameof(BarId))]
    public Bar Bar { get; set; }
}

我想使用以下queryValue的{​​{1}}作为关键字,从Bar对象创建Id,查找: / p>

Foo

在发生错误之前,我在控制台中收到以下警告:

  

Microsoft.EntityFrameworkCore.Query [20500]         LINQ表达式'来自<> f__AnonymousType0 ILookup<int, string> data = this.context.Foos .SelectMany(f => f.FooBars.Select(fb => new { f.Id, fb.Bar.Value })) .ToLookup(fb => fb.Id, fb => fb.Value); 1 [ReducibleNodeDemo.FooBar])将Bar fb.Bar值连接到(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 2 <generated>_0 in {from FooBar fb in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 2(Id = [f]。 Id,Value = [fb.Bar] .Value)}'无法翻译,将在本地进行评估。

我对EF Core还是比较陌生,但是已经使用EF6多年了,从未遇到过像这样的简单查询问题!

1 个答案:

答案 0 :(得分:4)

显然您遇到了当前的EF Core实现错误,因此请考虑将其报告给他们的问题跟踪器。

这似乎是由Select内部的SelectMany和内部lambda内部的外部参数f的使用引起的。解决方法是对元素选择器使用SelectMany重载:

.SelectMany(f => f.FooBars, (f, fb) => new { f.Id, fb.Bar.Value })

当您使用等效的LINQ查询语法时,我相信C#编译器会使用

(from f in this.context.Foos
 from fb in f.FooBars
 select new { f.Id, fb.Bar.Value })

在这种情况下的另一种解决方法/解决方案是直接从FooBar开始查询(具有显式联接实体的多对多优势之一)

this.context.Set<FooBar>()
    .Select(fb => new { fb.Foo.Id, fb.Bar.Value });