【发布时间】:2012-01-20 01:56:24
【问题描述】:
我正在使用 EF 4.1 Code First 并尝试对以下内容进行建模。
public class Apple
{
public int Id {get;set;}
}
public class Banana
{
public int AppleId {get;set;}
public int Id {get;set;}
public virtual ICollection<Coconut> Coconuts {get;set;}
}
public class Coconuts
{
public int AppleId {get;set;}
public int Id {get;set;}
public virtual ICollection<Banana> Bananas {get;set;}
}
数据库看起来像这样。
这是一个不遵循 EF 约定的现有架构,因此我使用 Fluent API 将实体映射到数据库。映射如下所示。
public class BananaMapping : EntityTypeConfiguration<Banana>
{
public BananaMapping()
{
HasKey(e => new { e.AppleId, e.Id })
.ToTable("Bananas", "fruit");
Property(e => e.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(e => e.Coconuts)
.WithMany(s => s.Bananas)
.Map(l =>
{
l.ToTable("BananaCoconuts", "fruit");
l.MapLeftKey("AppleId", "BananaId");
l.MapRightKey("AppleId", "CoconutId");
});
}
(Apple 和 Coconut 也被映射,但为简洁起见此处省略)
如果我这样离开它,它会因为共享列而生成 MetadataException。
"Schema specified is not valid. Errors: (110,6) : error 0019: Each property name in a type must be unique. Property name 'AppleId' was already defined."
为了解决这个问题,我在BananaCoconuts 上创建了一个计算列,它只是公开了AppleId 的一个不同命名的副本,并将其命名为BananaAppleId。我单独留下了 FK(显然)并将映射更改为如下所示...
HasMany(e => e.Coconuts)
.WithMany(s => s.Bananas)
.Map(l =>
{
l.ToTable("BananaCoconuts", "fruit");
l.MapLeftKey("BananaAppleId", "BananaId");
l.MapRightKey("AppleId", "CoconutId");
}
);
虽然有点臭,而且绝对是 hacktastic,但它确实让我通过了 MetadataException,直到我尝试从代码中添加一个新链接。
var banana = dataContext.FindBanana(appleId, bananaId);
var coconut = dataContext.FindCoconut(appleId, coconutId);
banana.Coconuts.Add(coconut);
dataContext.SaveChanges();
保存更改会引发 DbUpdateException
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
而内部(实际上是几个例外)......
{"The column \"BananaAppleId\" cannot be modified because it is either a computed column or is the result of a UNION operator."}
现在我没有主意了。 :) 数据库模式准确地模拟了我们需要的内容(计算列除外)。处理这个问题的最佳方法是什么?我并不热衷于将 BananaAppleId 设为“真实”列、更改外键以及存储不应该但可能不同步的重复数据。
【问题讨论】:
标签: entity-framework entity-framework-4.1 many-to-many ef-code-first fluent-interface