1

好的,您可以在下面看到我的简化模型。如果我遗漏了映射,那么每次我在下面的示例代码中添加一个相关的新集合(例如请求邀请)时,都会在我的基本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

如您所见,不同类型的存储在基类表中。不幸的是,表格末尾有一些流氓未使用的列似乎无用。我一直在尝试映射它们,以便这些列在生成的代码中消失。

这是类的映射部分。

...

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”上声明的导航属性“用户”已配置有冲突的多重性。

4

1 回答 1

0

您有两个来自实体的Act引用。U2在这种情况下,您需要为这两个编写绑定,因为 EF 不知道要映射哪个外键。

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 - 来自同一个表的两个外键

于 2013-01-07T03:45:45.703 回答