.Net实体多对多的SaveChanges

时间:2012-12-04 16:21:34

标签: c# .net entity-framework

我一直在玩实体核心类,例如DbContext,并在尝试保存对象时遇到以下错误:

  

保存不公开外键的实体时发生错误   他们关系的属性。 EntityEntries属性将   返回null,因为无法将单个实体标识为源   例外。可以在保存时处理异常   通过在实体类型中公开外键属性更容易。看到   InnerException以获取详细信息。

我基本上有很多对象,例如

comment   comment_category   category
id        comment_id         id
text      category_id        name

comment_category表是将注释映射到类别的组合主键

检索数据很好但是当我尝试保存它时会抱怨关系

我最感兴趣的模型看起来像

public class Comment
{
   [Key]
   public int Comment_Id {get;set;}
   public string Text {get;set;}
   public virtual List<Category> Categories { get; set; }
} 
public class Comment_Category
{
    [Key, Column(Order = 0)]
    public int Comment_Id {get;set;}
    [Key, Column(Order = 2)]
    public int Factor_Id {get;set;}
}

它的用途如

#Comments have Categories with Category Id filled and Comment Id null
List<Comment> comments = getComments();
using(dbContext db = new dbContext())
{
  foreach( Comment c in comments)
    db.Comments.add(c);
  db.SaveChanges();
}

我不完全确定为什么它能够轻松找到它但却节省了很多时间。我能想到的唯一区别是我保存的评论是新的,所以他们只有没有评论ID的评论类别只是类别ID。我假设它会保存注释并将comment_id分配给comment_category表,所以我不知道如何实现这个

我意识到我的方法可能是错误的,因为我使用映射表而不是类别的实际实体,所以如果有人知道更好的方式请分享。

谢谢!

1 个答案:

答案 0 :(得分:0)

在没有很多仪式的情况下,最简单的方法是获得一系列关于类别的评论,让实体框架推断M:M关系。它将自动创建一个包含主键和外键的CategoryComments表。

因此对于模型我们只需:

public class Comment
{
    [Key]
    public int Comment_Id { get; set; }
    public string Text { get; set; }
    public virtual List<Category> Categories { get; set; }
}

public class Category
{
    [Key]
    public int Category_Id { get; set; }
    public string Name { get; set; }
    public virtual List<Comment> Comments { get; set; }
}

用法如下:

public class MyDbContext : DbContext
{
    public DbSet<Comment> Comments { get; set; }
    public DbSet<Category> Categories { get; set; }
}

using (var db = new MyDbContext())
{
    var blue = new Category { Name = "Blue" };
    var red = new Category { Name = "Red" };
    db.Categories.Add(blue);
    db.Categories.Add(red);

    db.Comments.Add(new Comment
    {
        Text = "Hi",
        Categories = new List<Category> { blue }
    });

    db.SaveChanges();
}