3

我一直在使用 DbContext 等实体核心类,并在尝试保存对象时出现以下错误:

保存不为其关系公开外键属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。有关详细信息,请参阅 InnerException。

我基本上对多对多有我的erd,例如

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表,所以我不知道如何完成这个

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

谢谢!

4

1 回答 1

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();
}
于 2012-12-07T04:20:34.370 回答