我与外键有一对一的关系,但Cascade Delete
由于某种原因未启用。示例代码如下。
public class AppRegistration
{
public int AppRegistrationId { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[StringLength(100)]
public string Password { get; set; }
[StringLength(20)]
public string StudentOrAgent { get; set; }
// navigation properties
public virtual AppStatus AppStatus { get; set; }
public virtual Agreement Agreement { get; set; }
public virtual AnotherTable AnotherTable { get; set; }
}
带有外键的从属表在下面。
public class Agreement
{
[Key]
[ForeignKey("AppRegistration")]
public int AppRegistrationId { get; set; }
public DateTime DateAgreed { get; set; }
public virtual AppRegistration AppRegistration { get; set; }
}
当我尝试从生成的AppRegistrations
表中删除一个条目时,我得到一个Reference约束冲突。
我尝试将[Required]
放在依赖表中的导航属性上,但它没有做任何事情 - Update-Database
命令显示No pending code-based migrations.
消息。有任何想法吗?感谢。
更新 我收到以下错误消息:
The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.AppStatus_dbo.AppRegistrations_AppRegistrationId". The conflict occurred in database "MVCapp", table "dbo.AppStatus", column 'AppRegistrationId'.
答案 0 :(得分:8)
我决定在单独的示例项目中解决cascade delete
问题。我找到了以下博客& MSDN页面非常有用。
使用Code First
方法创建以下模型。
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public virtual Book Book { get; set; }
}
public class Book
{
public int CategoryId { get; set; }
public string BookTitle { get; set; }
public string BookAuthor { get; set; }
public string BookISBN { get; set; }
public virtual Category Category { get; set; }
}
(我意识到实体名称暗示了一对多的关系,但我试图模仿一对一的关系,就像我在顶部的原始问题一样。)
因此,在上述模型中,每个类别只能有一个图书。
在DbContext
- 派生类中添加以下内容。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Book>()
.HasKey(t => t.CategoryId);
modelBuilder.Entity<Category>()
.HasRequired(t => t.Book)
.WithRequiredPrincipal(t => t.Category)
.WillCascadeOnDelete(true);
}
(以上代码需要以下命名空间:System.Data.Entity
,System.Data.Entity.ModelConfiguration.Conventions
。)
这恰当地创建了一对一的关系。您将在每个表中都有一个主键,并且Book
表中的外键也会启用ON DELETE CASCADE
。
在上面的代码中,Category
实体使用了WithRequiredPrincipal()
和 t => t.Category
参数,其中参数是从属表中的外键列
如果您使用WithRequiredPrincipal()
而不使用参数,您将在Book
表中获得额外的列,并且Book
中将有两个外键}表指向CategoryId
表中的Category
。
我希望这些信息有所帮助。
<强>更新强>
后来我直接在这里找到答案:
http://msdn.microsoft.com/en-us/data/jj591620#RequiredToRequired
答案 1 :(得分:7)
您没有获得级联删除的原因是因为您的关系是可选的。
如果您想要所需的关系,即AppRegistration
必须有一个Agreement
,您可以使用(自动配置级联删除):
public class Agreement
{
...
[Required]
public AppRegistration AppRegistration{ get; set; }
}
如果您希望通过级联删除将关系设置为可选,则可以使用Fluent API进行配置:
modelBuilder.Entity<AppRegistration>()
.HasOptional(a => a.Agreement)
.WithOptionalDependent()
.WillCascadeOnDelete(true);