我有一个实体,其中包含许多不同的文档,这些文档与我数据库中的任何实体都存在未知关系。
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");
}
现在我希望在我的地址中有一个与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; }
}
使用以下映射:
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");
}
但是当我删除文档表中的图像时,它会删除相关的地址。
我想从地址到文档的OneWay-Deletation,但不是从文档到地址......?
我该如何实现?
谢谢。答案 0 :(得分: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指定为此关联中的主体,因此是级联行为。
但等等,这个故事还有更多内容!您可以通过两种方式创建一对一关联。首先是共享主键关联或一对一外键关联。您可以从here和here了解更多相关信息。看起来您想要通过外键(一对一外键关联)映射您的关联。如果是这样,你必须注意,依赖实体将始终携带外键,这意味着在你的情况下,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();
}
}
基本上WithOptionalPrincipal是您应该使用的方法:
将关系配置为可选:在关系的另一侧没有导航属性的可选项。正在配置的实体类型将是关系中的主体。关系所针对的实体类型将是依赖的实体类型,并包含主体的外键。
因此,从地址到文档正确地启用了级联删除。
答案 1 :(得分:0)
尝试删除OneToManyCascadeDeleteConvention:modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention >();