单向一对一关系实体框架,级联删除不起作用

时间:2016-03-30 15:36:51

标签: c# entity-framework-6

我想实现一对一的单向关系;但是级联删除不起作用。

我有以下课程:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public string Street { get; set; }
    //I don't want the StudentId foreign key or the property of Student class here 
}

在我的Context类中,我像这样映射关系:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>()
        .HasRequired(s => s.Address)
        .WithOptional()
        .Map(m => m.MapKey("Address_Id"))
        .WillCascadeOnDelete();
}

出于某种原因,删除address时,student对象被删除。

此外,我还想在AddressId类中添加外键属性(即Student),如下所示:

[ForeignKey("Address")]
[Column("Address_Id")]
public string AddressId { get; set; }

但是,当我尝试添加新迁移时出现此错误:

  

Address_Id:名称:类型中的每个属性名称必须是唯一的。物业名称&#39; Address_Id&#39;已定义。

我相信我会混淆一下(使用MapKeyAddressId的属性)。但是,我不知道如何解决这个问题。

我经历了this SO questionthis article;然而,到目前为止没有运气。

指向DotNetFiddle的链接。它没有工作,因为没有数据库。

2 个答案:

答案 0 :(得分:3)

你的外键应该是这样的:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    [ForeignKey("AddressId")]
    public Address Address { get; set; }        
    [Column("Address_Id")]
    public int AddressId { get; set; }
}

在您的流畅映射中,您只需要:

modelBuilder.Entity<Student>()
    .HasRequired(s => s.Address)
    .WillCascadeOnDelete(true);

或者您可以使用注释强制级联删除:

[Required]
[ForeignKey("AddressId")]
public Address Address { get; set; }

现在更新您的数据库,您的映射应该是正确的,并且删除应该级联。

答案 1 :(得分:3)

  

出于某种原因,删除address时,删除student对象时不会删除null

这是您定义的关系的正常行为。这不是数据注释或流畅配置的问题。如果你有不同的期望,你最好重新审视你的模型。

每个关系都有一个名为 principal 的一方,另一方称为依赖主要方面(a.k.a。主要,主要)是被引用的那一方。 依赖方(a.k.a。详细信息,辅助方)是引用主体的方。外键放在依赖方面,当关系为optional时,必须始终指向现有的主体cascade deleterequired的工作方式是删除主体记录时删除所有相关记录。

Code First如何确定关联中的主要和从属结束?部分所述,article提到您,EF始终使用required方作为委托并允许您仅在Address时选择一个。

说了这么多,让我们看看你有什么。

requiredStudentoptionalStudent。您还希望将FK放入Student,即Address引用Address

这意味着,在您的关系中,Student主体Address依赖。这意味着Student可能不存在cascade delete引用它。如果启用Address(与您一样),则删除Student将删除Should We Make the Associations Bidirectional?,而不是相反。

我认为所有这一切都应该解释为什么它的工作方式与现在一样,并且没有任何属性或配置可以帮助实现您的要求。如果您需要不同的内容,同一篇文章(以及相同系列中的相关内容)将介绍如何将关系配置为使用共享主键关联外键关联 地址方面。无论是单向还是双向绝对与问题没有任何共同之处 - 请参阅本文中的{{1}}部分。