【问题标题】:Many to Many relationship Entity Framework creating new rows多对多关系实体框架创建新行
【发布时间】:2014-03-31 11:26:36
【问题描述】:

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

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

反馈项:

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 表中新创建的反馈类别。

这不是我想要的工作

我想要以下:

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

======== 修复了 FeedbackSqlRepository 的 Create 方法中以下代码的问题:

 foreach (FeedbackCategory feedbackCategory in feedback.Categories)
            {
                context.Entry(feedbackCategory).State = EntityState.Unchanged;
            }
            context.FeedbackItems.Add(feedback);

            return context.SaveChanges();

【问题讨论】:

  • 您的问题可能来自使用不同的上下文对象来获取FeedbackCategory 和另一个来保存它们。试试这个stackoverflow.com/questions/5693843/…
  • 您能否向我们展示您在 FeedbackCategory、FeedbackItem 和 FeedbackCategoryFeedbackItems 之间的映射?您是否将一个实体映射到一个表?
  • EF 无法跨断开连接的上下文跟踪(子)实体。您需要自己处理跟踪,即在服务器上检查子实体是否已经存在,并将其标记为 EntityState.Unmodified 在调用“SaveChanges”之前。

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


【解决方案1】:

Entity Framework 不会检查实体内容并为您确定它们是新的还是添加的。

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

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

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

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

【讨论】:

  • 谢谢!这行得通。使用以下代码修复它:foreach (FeedbackCategory feedbackCategory in feedback.Categories) { context.Entry(feedbackCategory).State = EntityState.Unchanged; } context.FeedbackItems.Add(feedback); return context.SaveChanges();
  • 另外,您可以使用 Attach() 方法而不是 Add() 并为要添加的单个实体设置状态。可能不是性能差异,但您的代码会更清晰 imo。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2011-12-17
相关资源
最近更新 更多