繁体   English   中英

EF 6.0多对多关系编辑

[英]EF 6.0 Many to Many Relationships edits

我的Entity Framework 6.0存在问题,我的设置如下

public Post
{
    [Key]
    public int Id {get;set;}

    public String Name {get;set;}

    public virtual List<Category> Categories {get;set;}
}

public Category
{
    [Key]
    public int Id {get;set;}

    public string Name {get;set;}

    public virtual List<Post> Posts {get;set;}
}

所以当我尝试修改这样的列表之一时会出现问题

Posts.Categories.Remove(category);
Posts.Categories.Add(newCategory);
entities.SaveChanges();

我得到以下异常,只有在我尝试修改已创建且具有类别帖子时才会发生异常。

如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我不太确定在这种情况下该怎么做,我应该从类别中删除帖子吗? 请记住,通过从列表中删除类别 ,我只想从该集合中删除它,而不是从我的数据库中删除整个对象。 有什么建议么 ?

这是我给StackOverflow的第一篇文章,如果有人需要更多信息请告诉我。

我处理这些多对多关系的方式如下:(假设Post是来自DB的对象)

            var tmp = Post.Categories.Select(q => q).ToList();
            //delete all links
            foreach (var lab in tmp) {
                Posts.Categories.Remove(lab);
            }
            db.SaveChanges();

            //add new cats
            foreach (var lblgroup in myListofNewCats) {
               Post.Categories.Add(db.Categories.Single(q => q.ID=something);                    
            }

删除后提交更改时效果最佳。 如果没有更改,或者如果您再次删除并添加相同的实体而不在其间提交,则可能会引发一些错误。

我相信可能有更好的解决方案。

您可以定义中间表,然后只删除其中的记录。 这样,你就不会删除你自己现在正在做的类别本身。 我建议您修改模型如下:

public Post
{
    [Key]
    public int Id {get;set;}

    public String Name {get;set;}

    //For the many to 1 relationship
    public virtual ICollection <PostCategory> PostCategories{get;set;}

    //You wont need this anymore
    //public virtual List<Category> Categories {get;set;}
}

和...

public Category
{
    [Key]
    public int Id {get;set;}

    public string Name {get;set;}

    //For the many to 1 relationship
    public virtual ICollection <PostCategory> PostCategories{get;set;}

    //You wont need this anymore
    //public virtual List<Post> Posts {get;set;}
}

现在为新表创建模型,PostCategory,这将是中间表。 我喜欢使用单个键而不是双键。 您可以获得更大的灵活性,并且在使用存储库和开箱即用的控制器删除方法时很容易使用,但如果您愿意,可以使用双键 - 我没有在此处显示。 在此方法中,您需要在将记录添加到数据库之前自行检查重复项。

public PostCategory 
{
    [Key]
    public int Id {get;set;}  
    public int PostId {get;set;}
    public virtual Post Post {get;set;}

    public int CategoryId {get;set;}
    public virtual Category Category {get;set;}
}

请记住在dbcontext中定义“PostCategories”。 (我猜你知道怎么......?)

现在,当您想要删除帖子和类别之间的链接时,只需在控制器中删除PostCategory记录,如下所示:

//Find the record where postId is the PostId and the categoryId is the CategoryId
var postRecord = db.PostCategories.FirstOrDefault(x=>x.PostId==postId && x.CategoryId==categoryId);

if(postRecord!=null)
{
   db.PostCategories.Remove(postRecord)
   db.SaveChanges();
}

添加记录也很容易。 我在控制器中这样做...

//First create a record to add
PostCategory pc= new PostCategory()

//wire it up... EF adds the Id fields into the record. If you have a problem
// you can even add those.
pc.Category = category;
pc.Post = post;

//add it
db.PostCategories.Add(pc);
db.SaveChanges();

我喜欢这种方法,因为现在你可以在你的PostCategory表中保存额外的东西,例如Post等日期。我不喜欢很多很多关系,我相信它们迟早会分解为一对多和很多一个......以及后来当你必须“修改代码”时 - 至少可以说是痛苦。 我希望这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM