13

使用实体框架代码优先方法。

假设我有两个实体类:

[Table("Objects")]
public class DbObject : IValidatableObject
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

    public virtual ICollection<DbObjectProperty> Properties { get; set; }
}

[Table("ObjectProperties")]
public class DbObjectProperty
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }

    [Display(Name = "Object"), UIHint("Object")]
    public long ObjectId { get; set; }
    public virtual DbObject Object { get; set; }
}

这里要注意的点:

  • DbObject只有一个导航属性,但没有带有外键的列
  • DbObjectProperty有一个导航属性一个带有外键的对应列
  • 很明显,如果我删除一个对象,我希望它的属性随之而来,但如果我删除一个属性,我不希望整个对象消失。

OnModelCreatingDB 上下文的方法中,到目前为止,我有以下定义关系:

modelBuilder.Entity<DbObjectProperty>()
    .HasRequired(op => op.Object)
    .WithMany(obj => obj.Properties)
    .HasForeignKey(op => op.ObjectId)
    .WillCascadeOnDelete(false);

当然,这意味着不会发生级联删除。我的问题是:如果我将其更改为true,那是否符合我的要求?请记住,如果我删除一个对象,我希望它的属性随之而来,但如果我删除一个属性,我不希望整个对象消失。

此更改的自动生成的迁移代码(从falsetrue)是这样的:

DropForeignKey("ObjectProperties", "ObjectId", "Objects");
DropIndex("ObjectProperties", new[] { "ObjectId" });
AddForeignKey("ObjectProperties", "ObjectId", "Objects", "Id", cascadeDelete: true);
CreateIndex("ObjectProperties", "ObjectId");

我担心这似乎意味着删除一个属性会删除它的关联对象。会吗?

4

1 回答 1

14

数据库中关系的级联删除方向由该关系的主体(主/唯一键的表)和从属(外键的表)定义。

然后,如果您删除主体,所有具有与该主体的主/唯一键值相对应的外键值的依赖项也会被删除。从依赖到主体的方向没有级联删除。

在您的情况下,主体是DbObject,依赖是DbObjectProperty因为它是具有外键的实体/表。

反过来进行级联删除几乎没有意义 - 特别是在 x 对多关系中:如果删除依赖项 ( DbObjectProperty) 并且主体 ( DbObject) 将被自动删除,如果存在外键约束将被违反是指将要删除的主体的任何其他依赖项。

你不必担心。

于 2012-04-12T12:59:15.790 回答