abz*_*rak 13 c# entity-framework cascade one-to-many
这是我的情况:
public abstract class Article
{
[key]
public Guid Guid { get; set;}
public string Name { get; set;}
.
.
.
}
public class Download : Article
{
...
}
public abstract class Category : Article
{
...
}
public class DownloadCategory : Category
{
....
}
Run Code Online (Sandbox Code Playgroud)
然后我应该在下载之间有一个多对多的关系,DownloadCategory就像这样:
public class DownloadInCategory
{
[Key, Column(Order = 1), Required]
[ForeignKey("Download")]
Public Guid DownloadGuid { get; set; }
Public Download Download { get; set; }
[Key, Column(Order = 2), Required]
[ForeignKey("Category")]
Public Guid CategoryGuid { get; set; }
Public DownloadCategory Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我Add-Migration为DownloadInCategory实体调用创建的迁移时:
CreateTable("dbo.DownloadInCategories",
c => new
{
CategoryGuid = c.Guid(nullable: false),
DownloadGuid = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid })
.ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid)
.ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true)
.Index(t => t.CategoryGuid)
.Index(t => t.DownloadGuid);
Run Code Online (Sandbox Code Playgroud)
这是我的问题:你注意到它没有添加cascadeDelete: true到一个外键.为什么!!!!!!?????
我应该提一下,我没有改变任何modelbuilder公约.所以这个模式应该在迁移中删除Casscade.我的属性是[Required].
我究竟做错了什么?
多谢你们...
更新:
请注意,课程Article和Category课程abstract.我改变了上面的课程
更新2: 此架构没有逻辑问题.如果我手动编辑迁移,它将正常更新数据库.
更新3:
我的EF继承方法是TPC
更新4:
经过一些调查和测试似乎问题是继承的Category.何时DownloadCategory继承Category,未部署Cascade.但是当我DownloadCategory直接从Article 继承时,会部署Cascade.但为什么又一次?
我想这是因为:
DownloadCategory : Category : Article
Run Code Online (Sandbox Code Playgroud)
与
Download : Article
Run Code Online (Sandbox Code Playgroud)
关键在于 Article 类。多个DownloadCategories可以使用相同的Category,因此它不会级联删除,因为这可能会导致其他DownloadCategory的损坏。
这可能是实体框架的故障,因为您正在使用 TPC,所以应该推断出这一点。请查看这篇文章以获取解决方法。
具体来说这些部分:
在大多数情况下,实体框架可以推断哪个类型是依赖关系,哪个类型是关系中的主体。但是,当关系的两端都是必需的或者两端都是可选的时,实体框架无法识别依赖关系和主体。当需要关系的两端时,请在该方法之后使用
WithRequiredPrincipalor 。当关系的两端都是可选的时,请在该方法之后使用or 。WithRequiredDependentHasRequiredWithOptionalPrincipalWithOptionalDependentHasOptional
// Configure the primary key for the OfficeAssignment
modelBuilder.Entity<OfficeAssignment>()
.HasKey(t => t.InstructorID);
modelBuilder.Entity<Instructor>()
.HasRequired(t => t.OfficeAssignment)
.WithRequiredPrincipal(t => t.Instructor);
Run Code Online (Sandbox Code Playgroud)
您可以通过该
WillCascadeOnDelete方法对关系进行级联删除。如果依赖实体上的外键不可为空,则 Code First 会在关系上设置级联删除。如果依赖实体上的外键可为空,则 Code First 不会对关系设置级联删除,并且当删除主体时,外键将设置为null。您可以使用以下方法删除这些级联删除约定:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
Run Code Online (Sandbox Code Playgroud)
以下代码配置所需的关系,然后 禁用级联删除。
modelBuilder.Entity<Course>()
.HasRequired(t => t.Department)
.WithMany(t => t.Courses)
.HasForeignKey(d => d.DepartmentID)
.WillCascadeOnDelete(false);
Run Code Online (Sandbox Code Playgroud)