0

在我的 EF6 Code First 模型中,我有以下类:

class User : IdentityUser // so it has public string Id!
{
    public virtual long ItemId { get; set; }
    public virtual Item Item { get; set; }
}

class Item
{
    public virtual long Id { get; set;
    public virtual string UserId { get; set; }
    public virtual User User { get; set; }
}

在我的上下文中,我执行以下操作:

OnModelCreating(DbModelBuilder mB)
{
    mB.Entity<User>().HasOptional(x => x.Item).WithOptionalPrincipal(x => x.User).WillCascadeOnDelete(false);
}

但是,我的迁移产生以下内容:

CreateTable(
            "dbo.Items",
            c => new
                {
                    Id = c.Long(nullable: false, identity: true),
                    UserId = c.String(),
                    User_Id = c.String(maxLength: 128),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Users", t => t.User_Id)
            .Index(t => t.User_Id);

我忘了做什么?

更新:我也尝试添加[ForeignKey("User")]Item.UserId

Update2:我找到了一种解决方法,但它不是很漂亮......

OnModelCreating(DbModelBuilder mB)
{
    mB.Entity<User>().HasOptional(x => x.Item).WithMany().HasForeignKey(x => x.ItemId);
    mB.Entity<Item>().HasOptional(x => x.User).WithMany().HasForeignKey(x => x.UserId);
}
4

1 回答 1

0

据我了解,实体框架通过使 2 个实体共享相同的主键来强制实施一对一的关系。这意味着不需要单独的外键列,因为主键属性也充当外键。

因此,删除多余的外键并将 Item 的键的类型更改为字符串,以便它可以引用用户的 Id:

class User : IdentityUser // so it has public string Id!
{
    public virtual Item Item { get; set; }
}

class Item
{
    public string Id { get; set;}
    public virtual User User { get; set; }
}

现在,当关系的两端都是必需的或双方都是可选的时,实体框架无法识别依赖项和主体。依赖项是获取引用主体密钥的外键的那个。

所以试试这个:

modelBuilder.Entity<User>()
            .HasOptional(f => f.Item). //Item is dependent and 
                                       //gets the foreign key
            .WithOptionalPrincipal(s => s.User);

附带条件

我没有尝试过或做过这个,我没有得到的是这个。如果两端都是可选的,那么如何Item有一个外键User也可以是主键?主键是必需的,但可选的外键不是。所以它们不可能是一回事。

因此,如果 EF 现在添加了一个可选外键,我将为其添加一个唯一索引以确保它是 1 比 1。由于它可以为空,因此您需要在迁移中使用 sql

Sql("CREATE INDEX ON Item(User_Id) UNIQUE WHERE User_Id IS NOT NULL")

参考:

http://msdn.microsoft.com/en-us/data/jj713564

http://msdn.microsoft.com/en-us/data/jj591620.aspx

它在该页面上说:

当关系的两端都是可选的时,在 HasOptional 方法之后使用 WithOptionalPrincipal 或 WithOptionalDependent。

我是否在依赖或委托人上定义两个实体之间的关系?

于 2013-11-15T19:42:41.793 回答