EF表拆分:InvalidOperationException - 序列包含多个匹配元素

时间:2012-11-03 02:15:32

标签: entity-framework ef-code-first poco .net-4.5

我有一个我认为可能是EF错误的复制品。我想在两个实体之间拆分一个表。每个参与者都包含对第三个实体的引用。两个引用必须使用相同的外键属性名称公开。由于它们映射到同一个表中的列,因此使用配置(或者,在此示例中为属性)使列名称唯一。

当我尝试加载模型时,我从EF获得了上述异常。如果我修改其中一个FK属性的名称,那么错误就会消失。

这是我的模特。代码按原样运行。要重现此问题,请将Foo2.Foo3Id1重命名为Foo3Id,这是我需要的值。

你为什么要这样做?

如果您想知道为什么我需要两个属性具有相同的名称,这里是解释。

我有一个包含多个地址的表格(例如邮政地址和帐单邮寄地址)。这是一个现有的数据库,所以我无法更改表结构。每个地址由一系列标准列表示。每列的名称具有标识地址类型的前缀和标识地址部分的后缀,例如, BillingAddressLine1BillingAddressZipCodePostalAddressLine1

似乎使用复杂类型会处理这个问题。但是,还有一个复杂的问题:每个地址都包含一个引用CityId表的Cities。复杂类型don't support relationships and navigation properties。所以我的解决方案是使用表拆分,并将每组地址属性拆分为自己的实体。表示地址的每个实体都派生自基本类型,例如Address或实现接口IAddress

通过表拆分,我小心翼翼地观察到几个类型映射到同一个表的限制,they must all have navigation properties to each other

在下面的代码中,Foo1Foo2都是地址类型(并且会实现一些通用接口)。 Foo3City。这是我能提出的问题中最简单的问题。

代码示例

class Program
{
    static void Main(string[] args)
    {
        // Use NuGet to import EF 5 into the project.
        // This code is just enough to cause the metadata to be loaded and therefore demo the error.
        using (Context cx = new Context())
        {
            var qq = from f in cx.Foo3s
                     where f.Foo1s.Any()
                     select f;
        }
    }
}

[Table("Foo")]
public class Foo1
{
    [Key]
    public virtual int Id { get; set; }

    [Required]
    public virtual Foo2 Foo2 { get; set; }

    [ForeignKey("Foo3")]
    [Column("Foo1_Foo3Id")]
    public virtual int? Foo3Id { get; set; }

    public virtual Foo3 Foo3 { get; set; }
}

[Table("Foo")]
public class Foo2
{
    [Key]
    public virtual int Id { get; set; }

    [Required]
    public virtual Foo1 Foo1 { get; set; }

    // Re-name the following property to Foo3Id (rather than Foo3Id1) and the model won't load.
    // You get "InvalidOperationException: Sequence contains more than one matching element."
    [ForeignKey("Foo3")]
    [Column("Foo2_Foo3Id")]
    public virtual int? Foo3Id1 { get; set; }

    public virtual Foo3 Foo3 { get; set; }
}

[Table("Foo3")]
public class Foo3
{
    [Key]
    public virtual int Id { get; set; }

    [InverseProperty("Foo3")]
    public virtual ICollection<Foo1> Foo1s { get; set; }

    [InverseProperty("Foo3")]
    public virtual ICollection<Foo2> Foo2s { get; set; }
}

public class Context : DbContext
{
    public DbSet<Foo3> Foo3s { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Don't think we can configure 1:1 relationship using just attributes.
        var foo2 = modelBuilder.Entity<Foo2>();
        foo2.HasRequired(q => q.Foo1)
            .WithRequiredPrincipal(q => q.Foo2);
    }
}

这是一个错误吗?难道我做错了什么?这是一个已知的EF限制吗?

2 个答案:

答案 0 :(得分:1)

这确实是一个错误,现在已经修复了。请参阅http://entityframework.codeplex.com/workitem/643

答案 1 :(得分:1)

这个bug仍然在6.0左右。看看这里:https://entityframework.codeplex.com/workitem/546 +另一个相关的错误:https://entityframework.codeplex.com/workitem/2116