多对多关系实体框架创建新行

时间:2014-03-31 11:26:36

标签: c# entity-framework asp.net-mvc-4 entity-framework-5

我正在构建反馈功能。反馈应该有多个类别,应该可以根据类别找到反馈,因此存在多对多的关系。

我为此设置了以下代码,它首先设计为代码。

退款项目:

public class FeedbackItem
{
    public FeedbackItem()
    {

    }
    [Key]
    public long Id { get; set; }

    public virtual ICollection<FeedbackCategory> Categorys { get; set; }
    //public 
    public string Content { get; set; }
    public bool Notify { get; set; }
    public string SubscriptionUserName { get; set; }
    public string SubscriptionUserEmail { get; set; }
    public long SubscriptionId { get; set; }
}

反馈类别:

public class FeedbackCategory
{

   [Key]
   public int Id { get; set; }
   public string Value { get; set; }

   public virtual ICollection<FeedbackItem> Feedbacks { get; set; } 
}

数据库上下文:

public class FeedbackContext : DbContext, IFeedbackContext
{
    public FeedbackContext() : base("DefaultConnection")
    {
        //Database.SetInitializer<FeedbackContext>(new FeedbackContextDbInitializer());
    }
    public DbSet<FeedbackItem> FeedbackItems { get; set; }
    public DbSet<FeedbackCategory> Categories { get; set; } 
}

和初始化程序

class FeedbackContextDbInitializer : DropCreateDatabaseAlways<FeedbackContext>
{
    protected override void Seed(FeedbackContext context)
    {
        IList<FeedbackCategory> categories = new List<FeedbackCategory>()
            {
                new FeedbackCategory() { Value = "Android" },
                new FeedbackCategory() { Value = "API" }
            };

        foreach (var feedbackCategory in categories)
        {
            context.Categories.Add(feedbackCategory);
        }

        base.Seed(context);
    }
}

上面的代码在运行时会生成三个表。这些是FeedbackCategoriesFeedbackCategoryFeedbackItemsFeedbackItems

表FeedbackCategories附有一些已存在的类别。当我尝试创建一个包含一个或多个类别的新FeedbackItem时,就会出现问题。

我提供的Json如下:

{
"categorys": [
    {
        "$id": "1",
        "Feedbacks": [],
        "Id": 1,
        "Value": "Android"
    }
],
"subscriptionUserName": "name",
"subscriptionUserEmail": "my@email.com",
"content": "this is a feedback item",
"notify": false,
"subscriptionId": 2
}

将其转换为FeedbackItem并由以下代码处理

public class FeedbackSqlRepository : IFeedbackSqlRepository
{

    public int Create(FeedbackItem feedback)
    {
        if (feedback == null)
        {
            throw new ArgumentNullException("feedback", "FeedbackItem cannot be empty.");
        }
        using (var context = new FeedbackContext())
        {
            context.FeedbackItems.Add(feedback);
            return context.SaveChanges();
        }
    }
}

这里发生的事情是EF创建一个新的FeedbackItem,一个新的FeedbackCategory将创建的反馈项映射到FeedbackCategoryFeedbackItems表中新创建的反馈类别。

这不是我想要的工作

我想要以下内容:

创建新的FeedbackItem并尊重FeedbackCategory表中的现有FeedbackCategoryFeedbackItems。我对EF的了解太少,无法理解这里出了什么问题,以及如何做好首选工作。

====== 修复了FeedbackSqlRepository

中Create方法中以下代码的问题
 foreach (FeedbackCategory feedbackCategory in feedback.Categories)
            {
                context.Entry(feedbackCategory).State = EntityState.Unchanged;
            }
            context.FeedbackItems.Add(feedback);

            return context.SaveChanges();

1 个答案:

答案 0 :(得分:3)

实体框架不会检查实体内容,并确定它们是新的还是已添加。

DbSet.Add()会将对象图中的所有实体标记为已添加,并在调用SaveChanges()时生成插入。

DbSet.Attach()将所有标记为未修改的实体留下。

如果你的某些实体是新的,有些是修改的,有些只是引用,那么你应该使用Add()或Attach(),然后在调用SaveChanges()之前手动设置实体状态。

DbContext.Entry(entity).State = EntityState.Unmodified