【发布时间】:2013-05-05 14:45:11
【问题描述】:
下面是我的模型:
public class TMUrl
{
//many other properties
//only property with type Keyword
public List<Keyword> Keywords{get;set;}
}
public class Keyword
{
//many other properties
//only property with type TMUrl
public List<TMUrl> Urls{get;set;}
}
很明显,这两个实体都具有多对多关系。 我选择了 fluent api 来告诉实体框架这种关系,即
modelBuilder.Entity<TMUrl>
.HasMany(s => s.Keywords)
.WithMany(s => s.URLs).Map(s =>
{
s.MapLeftKey("KeywordId");
s.MapRightKey("UrlId");
s.ToTable("KeywordUrlMapping");
});
但是当我这样做时
url.Keywords.Add(dbKey); //where url is object of TMUrl,
//dbKey is an existing/new object of Keyword
db.SaveChanges();
我得到异常
An error occurred while saving entities that do not expose foreign key
properties for their relationships....
内部异常:
The INSERT statement conflicted with the FOREIGN KEY constraint
"KeywordMaster_Keyword". The conflict occurred in database "DbName",
table "dbo.KeywordMaster", column 'Id'.The statement has been terminated.
但是当我从另一边添加配置时,一切正常。 即
modelBuilder.Entity<KeyWord>
.HasMany(s => s.URLs)
.WithMany(s => s.Keywords)
.Map(s =>
{
s.MapLeftKey("KeywordId");
s.MapRightKey("UrlId");
s.ToTable("KeywordUrlMapping");
});
为什么?为什么我必须从两个实体中添加配置,我已经阅读了 here 和许多其他地方,其中一个实体的配置应该这样做。
什么情况,什么时候应该为关系中涉及的两个实体添加配置?
我需要明白这一点。为什么。请帮忙。
【问题讨论】:
-
"查看 InnerException 了解详情"。你是否?对于这个很少有用的异常,了解内部异常非常重要。
-
@Slauma,我已经用内部异常更新了问题,但请注意,从双方添加关系使其工作。
-
有趣的问题是,如果只有第二个映射(没有第一个映射)可以使其工作。如果是,我怀疑映射表中的列
KeywordId实际上是表URLs而不是Keywords的外键。 (仅当这是具有手动创建关系的现有数据库时才可能,而不是在您使用 Code-First 创建数据库时。) -
否@Slauma,我检查了 fk_relation 并且 KeywordId 映射到 KeywordMaster 的 Id。不知道为什么会这样;有时它只是有效;有时它只是不会。还有一件事,我有一个静态的单一上下文。我希望这不会导致这一切
-
是的,
Left和Right这两个术语在这里令人困惑,因为它们似乎表明它们与表中的列顺序有关。也许MapFirstEntityKey和MapSecondEntityKey会更清楚地表明它们实际上是指映射中的实体顺序。当然,如果 EF 创建数据库本身First和Left匹配。但是如果你手动做,顺序可以正好相反。
标签: c# entity-framework many-to-many ef-fluent-api