コード内の多対多の関係を保存するコードがいくつかあります。Entity Framework 4.1では正常に機能していましたが、Entity Framework 5に更新した後、失敗します。
次のエラーが発生します。
INSERTステートメントがFOREIGNKEY制約「FK_WebUserFavouriteEvent_Event」と競合しました。データベース「MainEvents」、テーブル「dbo.Event」、列「Id」で競合が発生しました。
カスタムマッピングでPOCOエンティティを使用しています。標準フィールドと多対1の関係マッピングは正常に機能しているようです。
アップデート
さて、SQL Profilerをインストールしましたが、プロットが厚くなりました...
exec sp_executesql N'insert [dbo].[WebUserFavouriteEvent]([WebUserId], [EventId])
values (@0, @1)
',N'@0 int,@1 int',@0=1820,@1=14
つまり:
WebUserId = @0 = 1820
EventId = @1 = 14
興味深いのは、EF5が外部キーを反転させたように見えることです... WebUserIdは14で、EventIdは1820である必要がありますが、現在のようにその逆ではありません。
マッピングコードを確認しましたが、99%すべて正しく設定しました。詳細については、 Entity Framework FluentAPI-RelationshipsMSDNの記事を参照してください。
注:これも保存に制限されておらず、SELECTも壊れていることもわかりました。
関連するすべてのコードは次のとおりです。
サービスレイヤー
public void AddFavEvent(WebUser webUser, Event @event)
{
webUser.FavouriteEvents.Add(@event);
_webUserRepo.Update(webUser);
}
リポジトリ
public void Update<T>(params T[] entities)
where T : DbTable
{
foreach (var entity in entities)
{
entity.UpdatedOn = DateTime.UtcNow;
}
_dbContext.SaveChanges();
}
注:リクエストごとに1つのDataContextアプローチを使用しているためwebUser
、@event
のコンテキストと同じコンテキストからロードされます_webUserRepo
。
エンティティ(DbTableのものについて心配する必要はありません)
public class Event : DbTable
{
//BLAH
public virtual ICollection<WebUser> FavouriteOf { get; set; }
//BLAH
}
public class WebUser : DbTable
{
//BLAH
public virtual ICollection<Event> FavouriteEvents { get; set; }
//BLAH
}
マッピング
public class EventMapping : DbTableMapping<Event>
{
public EventMapping()
{
ToTable("Event");
//BLAH
HasMany(x => x.FavouriteOf)
.WithMany(x => x.FavouriteEvents)
.Map(x =>
{
x.MapLeftKey("EventId");
x.MapRightKey("WebUserId");
x.ToTable("WebUserFavouriteEvent");
});
}
}
public class WebUserMapping : DbTableMapping<WebUser>
{
public WebUserMapping ()
{
HasMany(x => x.FavouriteEvents)
.WithMany(x => x.FavouriteOf)
.Map(m =>
{
m.MapLeftKey("WebUserId");
m.MapRightKey("EventId");
m.ToTable("WebUserFavouriteEvent");
});
}
}