我有一个复杂的模型,关于EF级联删除

时间:2012-08-16 03:53:18

标签: entity-framework cascade

代码优先,模型看起来像这样:

public class Post
{
    public int Id { get; set; }
    public string title { get; set; }
    public int fid { get; set; }
    public int uid { get; set; }
    public virtual lnk lnk { get; set; }
    public virtual user user { get; set; }
    public virtual ICollection<img> imgs { get; set; }
}

public class lnk 
{
    public int Id { get; set; }
    public string lnkman { get; set; }
}

public class model1:Post
{
    public string content { get; set; }
}

public class user
{
    public int uid { get;set; }
    public string Name {get;set;}
    public virtual ICollection<Post> posts { get; set; }
}

public class img
{
    public int id { get; set; }
    public string imgUrl { get; set; }
    public int pid { get; set; }
    public virtual Post post { get; set; }
}

public class PostContext : DbContext
{
    public DbSet<Post> posts { get; set; }
    public DbSet<user> users { get; set; }
    public DbSet<img> imgs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>().HasKey(i=>i.Id);
        modelBuilder.Entity<lnk>().HasKey(i => i.Id);
        modelBuilder.Entity<Post>().HasRequired(i => i.lnk).WithRequiredPrincipal();
        modelBuilder.Entity<Post>().ToTable("Post");
        modelBuilder.Entity<lnk>().ToTable("Post");

        modelBuilder.Entity<model1>().ToTable("model1");

        modelBuilder.Entity<user>().HasKey(i => i.uid).ToTable("user");

        modelBuilder.Entity<user>().HasMany(i => i.posts)
                                  .WithRequired(i => i.user)
                                  .HasForeignKey(i =>i.uid).WillCascadeOnDelete(false);

        modelBuilder.Entity<img>().HasKey(i => i.id).ToTable("img");

        modelBuilder.Entity<Post>().HasMany(i => i.imgs)
                                   .WithRequired(i => i.post)
                                   .HasForeignKey(i => i.pid)
                                   .WillCascadeOnDelete(false);
    }
}

添加和列表方法效果很好。但是像这样删除:

using (var db = new PostContext())
{
    //model1 ToDel = new model1{ Id=id };
    //b.Entry(ToDel).State = System.Data.EntityState.Deleted;
    var ToDel = db.users.Single(i => i.uid == id);

    db.users.Remove(ToDel);
    db.SaveChanges();
    return id + "DE: well done!" ;
}
  

System.Data.SqlClient.SqlException:DELETE语句,带有REFERENCE约束“FK_dbo.Post_dbo.user_uid”冲突。冲突发生在数据库“jefunfl”,表“dbo.Post”,列'uid'

我希望删除具有用户帖子的用户,以及带有帖子的帖子的帖子。 我怎样才能做到这一点?有人可以给出任何提示吗?

顺便说一句,我的中文英文可能很有趣。原谅我。 这是我的第一篇文章,但我不是新人。感谢

1 个答案:

答案 0 :(得分:0)

绕过一天,我找到了。谢谢你回答我。

1: 我删除了WillCascadeOnDelete()方法,所以让我们通过约定来做。

2: 我发现,当我删除帖子时,我无法直接删除此语句,如ToDel = db.posts.Single(i =&gt; i.Id == id) 但是这个: ToDel = db.posts.Include(i =&gt; i.lnk).Single(i =&gt; i.Id == id) post和lnk有一个名为table splitting的relatialship。两者都映射到同一个帖子表。删除帖子时,EF可以按约定自动删除post.imgs。删除用户会发生什么?所以我明白了。我的代码打击:

            var ToDel = db.users.Include(i => i.posts)
                                .Single(i => i.uid == id);
            var PostToDel = db.posts.Include(i => i.lnk)
                              .Single(i => i.Id == ToDel.uid);
            db.posts.Remove(PostToDel);
            db.users.Remove(ToDel);
            db.SaveChanges();
这将很好用。甚至不完美。但它可以做到我想要的,没有例外。

最后,最大的问题是post class和lnk类有一个“table splitting”。 当删除帖子时我们应该明确包含。

我不知道你是否能理解我,我的英语非常难看。我有勇气愚蠢。 感谢你。我很高兴