【问题标题】:Problem while working with many-to-many relationships in Entity Framework在实体框架中处理多对多关系时出现问题
【发布时间】:2009-08-13 18:57:23
【问题描述】:

我从 X 类创建了一些项目。

我将它们添加到 de base,执行 SaveChanges 和所有这些...

类 Y 与 X 具有多对多关系。

使用另一个上下文,我创建了一个 Y 实例,将我创建的元素放入 X 的集合中。

我将 Y 添加到 Y 实体集,没关系。

当我执行 Context.SaveChanges() 时,我得到:

跨实体或关联的共享值在多个位置生成。检查映射是否不会将 EntityKey 拆分为多个服务器生成的列。

你见过这个错误吗?

编辑:一开始,我设置了 1-to-many,后来我注意到它实际上是 many-to-many。

EDIT 2:显示完成的方式。与使用 .net 的许多人不同,我们确实使用层(业务、数据......)。这是测试用例:

[TestMethod]
public void WorksWithAreaCategories()
{
    using (new TransactionScope())
    {
        //arrange
        var context = ContextFactory.Create();
        var categoryBusiness = new CategoryBusiness(context);
        var category = new Category
                {
                    Name = "TestCategory###"
                };
        categoryBusiness.Add(category);

        var areaBusiness = new AreaBusiness(context);
        var area = new Area
                {
                    Name = "TestArea###",
                    Description = "TestAreaDescription###",
                    Categories = new List<Category> {category}
                };

        //act
        areaBusiness.Add(area);

        //assert
        var areaFromDb = areaBusiness.FindById(area.AreaID);
        Assert.IsNotNull(areaFromDb.Categories);
        Assert.IsTrue(areaFromDb.Categories.Count > 0);
        Assert.IsTrue(areaFromDb.Categories.Any(c => c.CategoryID == category.CategoryID));
    }
}

它们共享相同的上下文。业务层在每个 Add 结束时调用 SaveChanges。

【问题讨论】:

    标签: c# visual-studio-2008 entity-framework


    【解决方案1】:

    我是如何解决的:

    将两者都添加后,我与Update建立了关系。

    [TestMethod]
    public void WorksWithAreaCategories()
    {
        using (new TransactionScope())
        {
            //arrange
            var context = ContextFactory.Create();
            var categoryBusiness = new CategoryBusiness(context);
            var category = new Category
                            {
                                Name = "TestCategory###"
                            };
            categoryBusiness.Add(category);
    
            var areaBusiness = new AreaBusiness(context);
            var area = new Area
                            {
                                Name = "TestArea###",
                                Description = "TestAreaDescription###",
                            };
            areaBusiness.Add(area);
    
            //act
            area.Categories = new List<Category> { category };
            areaBusiness.Update(area);
    
            //assert
            var areaFromDb = areaBusiness.FindById(area.AreaID);
            Assert.IsNotNull(areaFromDb.Categories);
            Assert.IsTrue(areaFromDb.Categories.Count > 0);
            Assert.IsTrue(areaFromDb.Categories.Any(c => c.CategoryID == category.CategoryID));
        }
    }
    

    【讨论】:

      【解决方案2】:

      当错误显示“多个位置”时,它实际上意味着多个上下文。数据“属于”特定上下文,如果您尝试在上下文之间移动数据,则会遇到问题。

      有两种方法可以解决它:

      • 在相同的上下文中做所有事情
      • 创建 Y 实例时,先从磁盘读取 X 元素,使它们处于相同的上下文中,然后再将 X 元素添加到 Y。

      根据评论编辑:

      尝试使用单个保存更改。

      【讨论】:

      • 即使使用相同的上下文,我也会遇到同样的问题。 =/
      • 嗯,我不能,因为它们是不同的操作。我通过业务层使用这些操作,所以我不能只保存最后一个,我将更新问题以向您展示它的完成方式。有趣的是,同样的事情不会在其他多对多关系中抛出任何错误。
      • 第二个选项我没看懂,也许我可以通过这种方式解决。当我创建 Y 实例时,我执行 linq 查询以从上下文加载 X 元素,我不直接使用实体对象,因为我没有它们(测试用例适用于 POCO,而不是实体,我必须映射它们)
      • 即使在插入类别 (X) 时不保存上下文,我也会遇到同样的问题:S
      • 可怕的评论:事件之前没有添加 Xs,我遇到了同样的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 2017-01-28
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多