与OneWay CascadeOnDelete的一对一或零关系

Ali*_*ani 3 entity-framework ef-code-first

我有一个实体,其中包含许多不同的文档,与我的数据库中的任何实体都存在未知关系.

public class Document : BaseEntity
{

    public string Filename { get; set; }

    public string MIMEType { get; set; }
    public int? Length { get; set; }

    public byte[] Content { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

而codefirst-mapping是:

    public DocumentConfiguration()
    {
        Property(x => x.Filename).HasMaxLength(300).IsRequired();
        Property(x => x.MIMEType).HasMaxLength(300).IsRequired();
        Property(x => x.Length).IsOptional();
        Property(x => x.Content).IsOptional().HasColumnType("varbinary(max)");


        ToTable("Document"); 
    }
Run Code Online (Sandbox Code Playgroud)

现在我希望在我的addressentity中有一个与document-table的可选关系,如下所示:

public class Address : BaseEntity
{

    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Additional { get; set; }


    public string Street { get; set; }
    public string HousNr { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }

    public virtual Document Image { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

使用以下映射:

    public AddressConfiguration()
    {

        Property(x => x.Name1).IsRequired().HasMaxLength(250);
        Property(x => x.Name2).HasMaxLength(250);
        Property(x => x.Additional).HasMaxLength(250);


        Property(x => x.Street).HasMaxLength(250);
        Property(x => x.HousNr).HasMaxLength(10);
        Property(x => x.ZipCode).HasMaxLength(10);
        Property(x => x.City).HasMaxLength(100);


        HasOptional(x => x.Image)
            .WithOptionalDependent()
            .Map(map => map.MapKey("ImageId")).WillCascadeOnDelete();


        ToTable("Address");

    }
Run Code Online (Sandbox Code Playgroud)

但是当我删除文档表中的图像时,它会删除相关地址.

我想要一个从地址到文档的OneWay-Deletation,但不是从文档到地址......?

我该如何实现呢?

谢谢.

Mor*_*avi 5

它从文档到地址具有级联的原因是因为您使用了WithOptionalDependent方法.从文档:

将关系配置为可选:在关系的另一侧没有导航属性的可选.正在配置的实体类型将是依赖项,并包含主体的外键.关系所针对的实体类型将是关系中的主体.

在AddressConfiguration方法中考虑以下代码行:

HasOptional(x => x.Image)         // The entity type being configured is Address
   .WithOptionalDependent()...   // The entity type that the relationship targets
                                //  is Document (x.Image)
Run Code Online (Sandbox Code Playgroud)

这意味着您有效地指定Address作为依赖,而Document作为此关联中的主体,因此是级联行为.

但等等,这个故事还有更多!您可以通过两种方式创建一对一关联.首先是共享主键协会一对一外键协会.您可以从这里这里了解更多关于它们的信息.看起来您想要通过外键(一对一外键关联)映射您的关联.如果是这样,你必须注意,依赖实体将始终携带外键,这意味着在你的情况下,Document实体将有一个AddressId引用地址实体上的AddressId(你做了反向,这是不正确的.).

总而言之,您的对象模型和流畅的API代码应如下所示:

public class Address 
{
    public int AddressId { get; set; }
    public virtual Document Image { get; set; }
}

public class Document 
{
    public int DocumentId { get; set; }
}

class Context : DbContext
{
    public DbSet<Address> Addresses { get; set; }
    public DbSet<Document> Documents { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Address>()  // The entity being configured is Address
                    .HasOptional(x => x.Image)  
                    .WithOptionalPrincipal()
                    .Map(map => map.MapKey("AddressId"))
                    .WillCascadeOnDelete();
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,WithOptionalPrincipal是你应该使用的方法:

将关系配置为可选:在关系的另一侧没有导航属性的可选.正在配置的实体类型将是关系中的主体.关系所针对的实体类型将是依赖的实体类型,并包含主体的外键.


结果,级联删除从地址到文档正确打开.