我有一个我认为可能是EF错误的复制品。我想在两个实体之间拆分一个表。每个参与者都包含对第三个实体的引用。两个引用必须使用相同的外键属性名称公开。由于它们映射到同一个表中的列,因此使用配置(或者,在此示例中为属性)使列名称唯一。
当我尝试加载模型时,我从EF获得了上述异常。如果我修改其中一个FK属性的名称,那么错误就会消失。
这是我的模特。代码按原样运行。要重现此问题,请将Foo2.Foo3Id1
重命名为Foo3Id
,这是我需要的值。
如果您想知道为什么我需要两个属性具有相同的名称,这里是解释。
我有一个包含多个地址的表格(例如邮政地址和帐单邮寄地址)。这是一个现有的数据库,所以我无法更改表结构。每个地址由一系列标准列表示。每列的名称具有标识地址类型的前缀和标识地址部分的后缀,例如, BillingAddressLine1
,BillingAddressZipCode
和PostalAddressLine1
。
似乎使用复杂类型会处理这个问题。但是,还有一个复杂的问题:每个地址都包含一个引用CityId
表的Cities
。复杂类型don't support relationships and navigation properties。所以我的解决方案是使用表拆分,并将每组地址属性拆分为自己的实体。表示地址的每个实体都派生自基本类型,例如Address
或实现接口IAddress
。
通过表拆分,我小心翼翼地观察到几个类型映射到同一个表的限制,they must all have navigation properties to each other。
在下面的代码中,Foo1
和Foo2
都是地址类型(并且会实现一些通用接口)。 Foo3
是City
。这是我能提出的问题中最简单的问题。
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限制吗?
答案 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