1

わかりました、以下の単純化されたモデルを見ることができます。マッピングを省略した場合、次のサンプル コードのRequestsInvitesなど、関連する新しいコレクションを追加するたびに、データベース内のベースBusinessCardActionsテーブルにあらゆる種類の重複キーが生成されます。

// DbContext 

public DbSet<BusinessCardAction> BusinessCardActions { get; set; }

// Classes
public abstract class BusinessCardAction
{
    public Int32 Id { get; set; }
    public User User { get; set; }
    public Int32 UserId { get; set; }
    public Int32 OtherUserId { get; set; }
    public User OtherUser { get; set; }
    public Guid UniqueId { get; set; }
    public String Email { get; set; }
    public String OtherEmail { get; set; }
    public Int32 UserAction { get; protected set; }
    public DateTime ActionDate { get; set; }
}
public abstract  class StatusAction : BusinessCardAction
{
    public Int32 Status { get; set; }
    public String Password { get; set; }
}
public class Request : StatusAction
{
    public Int32 InviteId { get; set; }
}
public class Acceptance : BusinessCardAction
{
}
public class Nudge : BusinessCardAction
{
}

public class User
{
    public Int32 Id { get; set; }
    public ICollection<Associate> AssociatedUsers { get; set; }
    public ICollection<Request> Requests { get; set; }
    public ICollection<Invite> Invites{ get; set; }
    public ICollection<BusinessCardAction> RecentActions { get; set; }
}

現在、基本クラスの派生クラス間で外部キー列を共有する方法がない場合、これらの重複列に大きな問題はありません。しかし、これは起こりません。次の挿入後のリンクに示されているデータは、それらがすべて目的のUserId列を共有していることを示しています。

いくつかのテスト コードを作成し、データが追加された後に結果へのリンクを追加しました。

var accept = new Acceptance()
    {
        Email = "tsie@mail.com",
        OtherUserId = 2,
        UserId = 1,
        OtherEmail = "jaim@l8.ca",
        Associate = "James",
        ActionDate = DateTime.Now
    };
var invite = new Invite()
    {
        Email = "tsie@ail.com",
        OtherUserId = 2,
        UserId = 1,
        OtherEmail = "jai@llev8.ca",
        Status = 1,
        Password = "Password",
        ActionDate = DateTime.Now
    };
var request = new Request()
    {
        Email = "tst@mail.com",
        OtherUserId = 2,
        UserId = 1,
        OtherEmail = "jai@llev8.ca",
        Password = "********",
        Status = 2,
        ActionDate = DateTime.Now
    };

var nudge = new Nudge()
    {
        Email = "tsi@ail.com",
        OtherUserId = 2,
        UserId = 1,
        OtherEmail = "jai@lev8.ca",
        ActionDate = DateTime.Now
    };
_businessCardActionService.Data.BusinessCardActions.Add(accept);
_businessCardActionService.Data.BusinessCardActions.Add(invite);
_businessCardActionService.Data.BusinessCardActions.Add(request);
_businessCardActionService.Data.BusinessCardActions.Add(nudge);
_businessCardActionService.Save();

このリンクに従って、前述の挿入後の BusinessCardActionsData を表示します http://screencast.com/t/JKBcpaCT742

ご覧のとおり、さまざまなタイプの for が基本クラス テーブルに格納されています。残念ながら、テーブルの最後に、役に立たないように見えるいくつかの不正な未使用の列があります。これらの列が生成されたコードで消えるように、それらをマップしようとしています。

そして、これがクラスのマッピング セクションです。

...

modelBuilder.Entity<Nudge>()
    .HasRequired(i => i.User)
    .WithMany()
    .HasForeignKey(i => i.UserId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Acceptance>()
    .HasRequired(a => a.User)
    .WithMany()
    .HasForeignKey(a => a.UserId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Nudge>()
    .HasRequired(i => i.OtherUser)
    .WithMany()
    .HasForeignKey(i => i.OtherUserId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Acceptance>()
    .HasRequired(a => a.OtherUser)
    .WithMany()
    .HasForeignKey(a => a.OtherUser)
    .WillCascadeOnDelete(false);

適切に生成されたデータベーステーブルの代わりに、次のエラーが表示されます。これはある程度意味がありますが、同時にどういうわけか私をひどく悩ませます. これを行う方法があるかもしれませんが、まだ見つけていません。

タイプ 'Ellevate.BusinessCards.Models.BusinessCardAction' で宣言されたナビゲーション プロパティ 'User' は、競合する多重度で構成されています。

4

1 に答える 1

0

ActからU2エンティティへの参照が 2 つあります。その場合、EF はどの外部キーをマップするかわからないため、これら 2 つのバインディングを記述する必要があります。

modelBuilder.Entity<ACT>()
    .HasRequired(a => a.OtherU2)
    .WithMany(u2=>u2.OtherActs)
    .HasForeignKey(a => a.OtherU2Id)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<ACT>()
    .HasRequired(a => a.U2)
    .WithMany(u2=>u2.OtherActs)
    .HasForeignKey(a => a.U2Id)
    .WillCascadeOnDelete(false);  

正確な答えを出すには、もっと情報が必要だと思います。エンティティの匿名化で何かを見逃したようです。ここで詳細情報を参照してくださいEntity Framework Code First - 同じテーブルからの2つの外部キー

于 2013-01-07T03:45:45.703 に答える