3

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

public class Document : BaseEntity
{

    public string Filename { get; set; }

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

    public byte[] Content { get; set; }

}

并且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"); 
    }

现在我想要一个与我的地址中的文档表的可选关系,如下所示:

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; }

}

使用以下映射:

    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");

    }

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

我想要一个从地址到文件的单向删除,而不是从文件到地址...?

我该如何实施?

谢谢你。

4

2 回答 2

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)

这意味着您在此关联中有效地将 Address 指定为依赖项,并将 Document 指定为主体,从而产生级联行为。

但是等等,这个故事还有更多!您可以通过两种方式创建一对一关联。首先是共享主键关联一对一外键关联您可以从这里这里阅读更多关于它们的信息。看起来您想通过外键(一对一外键关联)映射您的关联。如果是这样,您必须注意依赖实体将始终携带外键,这意味着在您的情况下,文档实体将有一个 AddressId 引用 Address 实体上的 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();
    }
}

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

将关系配置为可选:关系另一端没有导航属性的可选。正在配置的实体类型将是关系中的主体。关系目标的实体类型将是从属的,并包含主体的外键。


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

于 2012-04-05T18:59:54.410 回答
0

尝试删除 OneToManyCascadeDeleteConvention: modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention >();

于 2012-04-04T13:54:18.183 回答