我只是在使用MVC 4并且在我的应用程序中遇到错误,我需要一些修复帮助。
我有一个作者&书桌。 Author表是父表,您可以将多个Books与每个作者关联。
一切顺利,直到我尝试删除仍然分配给他的书籍的作者。当发生这种情况时,我在SaveChanges()收到错误说明:
DELETE语句与REFERENCE约束冲突 “FK_Book_Author”。
错误很有意义,但我希望应用程序向用户提供一个很好的错误消息,而不是简单地爆炸。
如何在模型中定义此关系,以便在删除与其关联的子项的记录时不会导致应用程序爆炸?
public partial class Author
{
public Author()
{
this.Book = new HashSet<Book>();
}
[Key]
public int AuthorId { get; set; }
[Required]
public string AuthorName { get; set; }
public virtual Book Book { get; set; }
}
public partial class Book
{
[Key]
public int BookId { get; set; }
[Required]
public string BookName { get; set; }
[Required]
[ForeignKey("Author")]
public string AuthorId { get; set; }
}
我最近开始尝试覆盖OnModelCreating,但似乎没有任何影响。
public partial class BookEntities : DbContext
{
public BookEntities()
: base("name=BookEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>().HasRequired(p => p.Author)
.WithMany(b => b.Books)
.HasForeignKey(p => p.AuthorId);
modelBuilder.Entity<Author>()
.HasMany(p => p.Books)
.WithRequired(b => b.Author)
.WillCascadeOnDelete(false);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
}
答案 0 :(得分:0)
如果我也使用了流畅的API,我通常不会使用这些属性,所以这段代码将完全是常规和流畅的API。
您的帖子没有指定,但经典书籍=&gt;作者模型是多对多的关系。您的实体代码似乎在说只有一位作者和一本书,而您的流利代码似乎暗示有书籍和作者的集合。
FWIW,这就是我的意思:
public class Author
{
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string BookName { get; set; }
public virtual ICollection<Author> Authors { get; set; }
}
和覆盖:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.HasMany(a => a.Books)
.WithMany(b => b.Authors)
.Map(m =>
{
m.ToTable("AuthorBooks");
m.MapLeftKey("AuthorId");
m.MapRightKey("BookId");
});
}
这将产生db:
我相信这就是获得级联所需的全部内容,按惯例,它应该执行级联。
如果这不是您想要的,请发布。
塔尔
答案 1 :(得分:0)
在这个问题上花费了一天的时间后,我决定在DeleteConfirmed方法中添加一些自定义代码,以防止出现错误。提醒用户该记录无法删除。 这可能不是处理这种情况的最佳方法,但它是有效的。
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Author author = db.Authors.Find(id);
// Count # of Books for this Author
int count = (from book in db.Books
where book.BookId == id
select book.BookId).Count();
// Prevent deletion of this record has any associated records
if (count> 0)
{
TempData["errors"] = "Bad user! You can't delete this record yet!";
return RedirectToAction("Delete");
}
else
{
db.Categories.Remove(category);
db.SaveChanges();
return RedirectToAction("Index");
}
}