entity-framework - GraphDiff 和 EF6.1 – 递归多对多关系

标签 entity-framework recursion graphdiff

我在 GraphDiff 附加具有递归多对多关系的对象时遇到问题。我正在使用 GraphDiff 2.0.1 和 Entity Framework 6.1.1。

该程序管理的食谱可以有 0-n 个 RecipeLines,其中包含到另一个 Recipe 的链接,该食谱是 ComponentRecipe,并且具有 RecipeLines 等等。

我将一个菜谱对象传递到存储库中,该存储库有 1 个菜谱行,该行上的菜谱对象指向父级,而 ComponentRecipe 对象指向另一个菜谱。

当 GraphDiff 附加该项目时,它返回的 AttachedItem 有 2 个配方行,并且这两行都是相同的,并且 ComponentRecipe 指向与在自身上创建循环的 Recipe 相同的对象。

我不确定这是否是 GraphDiff 的问题,或者更有可能是我的 EF 映射或 GraphDiff 映射出了问题。感谢任何帮助,如果您需要更多信息,请告诉我,我可以提供一个简单的程序来演示此问题。

领域模型

public class Recipe : EntityBase
{
        public override object Key
        {
            get { return Id; }
        }

        public int Id { get; set; }

        public string Name { get; set; }

        public virtual IList<RecipeLine> RecipeLines { get; set; }

 }

public class RecipeLine : EntityBase
{
        public override object Key
        {
            get { return Id; }
        }

        public int Id { get; set; }

        public int RecipeId { get; set; }

        public int ComponentRecipeId { get; set; }

        public decimal Quantity { get; set; }

        public virtual Recipe Recipe { get; set; }

        public virtual Recipe ComponentRecipe { get; set; }
}

数据上下文

class DataContext : DbContext
    {
        public DataContext()
            : base("Connection")
        {
            Configuration.ProxyCreationEnabled = false;
            Configuration.LazyLoadingEnabled = false;
        }

        public DbSet<Recipe> Recipes { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer<DataContext>(null);

            modelBuilder.Entity<Recipe>().ToTable("Recipes");
            modelBuilder.Entity<Recipe>().HasKey(x => x.Id);
            modelBuilder.Entity<Recipe>().Property(x => x.Id).HasColumnName("Id");
            modelBuilder.Entity<Recipe>().Property(x => x.Name).HasColumnName("Name");

            modelBuilder.Entity<RecipeLine>().ToTable("RecipeLines");
            modelBuilder.Entity<RecipeLine>().HasKey(x => x.Id);
            modelBuilder.Entity<RecipeLine>().Property(x => x.Id).HasColumnName("Id");
            modelBuilder.Entity<RecipeLine>().Property(x => x.RecipeId).HasColumnName("RecipeId");
            modelBuilder.Entity<RecipeLine>().Property(x => x.ComponentRecipeId).HasColumnName("ComponentRecipeId");
            modelBuilder.Entity<RecipeLine>().Property(x => x.Quantity).HasColumnName("Quantity").HasPrecision(18, 5);

            modelBuilder.Entity<Recipe>().HasMany(x => x.RecipeLines).WithRequired(x => x.Recipe).HasForeignKey(x => x.RecipeId);

            modelBuilder.Entity<RecipeLine>().HasRequired(x => x.ComponentRecipe).WithMany().HasForeignKey(x => x.ComponentRecipeId);

        }
    }

存储库

public override void UpdateEntity(IEntity entity)
{
            using (var context = new DataContext())
            {
                context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
                var item = (Recipe)entity;
                var attachedItem = context.UpdateGraph(item,
                    a => a.OwnedCollection(b => b.RecipeLines, c => c.AssociatedEntity(d => d.ComponentRecipe)));
                context.SaveChanges();
            }
}

数据上下文登录附加

Opened connection at 14/09/2014 16:57:06 +01:00

SELECT 
    [Project1].[Id] AS [Id], 
    [Project1].[Name] AS [Name], 
    [Project1].[C1] AS [C1], 
    [Project1].[Id1] AS [Id1], 
    [Project1].[RecipeId] AS [RecipeId], 
    [Project1].[ComponentRecipeId] AS [ComponentRecipeId], 
    [Project1].[Quantity] AS [Quantity], 
    [Project1].[Id2] AS [Id2], 
    [Project1].[Name1] AS [Name1]
    FROM ( SELECT 
        [Limit1].[Id] AS [Id], 
        [Limit1].[Name] AS [Name], 
        [Join1].[Id1] AS [Id1], 
        [Join1].[RecipeId] AS [RecipeId], 
        [Join1].[ComponentRecipeId] AS [ComponentRecipeId], 
        [Join1].[Quantity] AS [Quantity], 
        [Join1].[Id2] AS [Id2], 
        [Join1].[Name] AS [Name1], 
        CASE WHEN ([Join1].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM   (SELECT TOP (2) [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name]
            FROM [dbo].[Recipes] AS [Extent1]
            WHERE 11 = [Extent1].[Id] ) AS [Limit1]
        LEFT OUTER JOIN  (SELECT [Extent2].[Id] AS [Id1], [Extent2].[RecipeId] AS [RecipeId], [Extent2].[ComponentRecipeId] AS [ComponentRecipeId], [Extent2].[Quantity] AS [Quantity], [Extent3].[Id] AS [Id2], [Extent3].[Name] AS [Name]
            FROM  [dbo].[RecipeLines] AS [Extent2]
            INNER JOIN [dbo].[Recipes] AS [Extent3] ON [Extent2].[ComponentRecipeId] = [Extent3].[Id] ) AS [Join1] ON [Limit1].[Id] = [Join1].[RecipeId]
    )  AS [Project1]
    ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC


-- Executing at 14/09/2014 16:57:06 +01:00

-- Completed in 1 ms with result: SqlDataReader



Closed connection at 14/09/2014 16:57:06 +01:00

Opened connection at 14/09/2014 16:57:07 +01:00

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name]
    FROM [dbo].[Recipes] AS [Extent1]
    WHERE [Extent1].[Id] = 10


-- Executing at 14/09/2014 16:57:07 +01:00

-- Completed in 0 ms with result: SqlDataReader



Closed connection at 14/09/2014 16:57:07 +01:00

SaveChanges 上的数据上下文日志

Opened connection at 14/09/2014 16:58:45 +01:00

INSERT [dbo].[RecipeLines]([RecipeId], [ComponentRecipeId], [Quantity])
VALUES (@0, @1, @2)
SELECT [Id]
FROM [dbo].[RecipeLines]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()


-- @0: '11' (Type = Int32)

-- @1: '11' (Type = Int32)

-- @2: '1' (Type = Decimal, Precision = 18, Scale = 5)

-- Executing at 14/09/2014 16:58:46 +01:00

-- Completed in 1 ms with result: SqlDataReader



Closed connection at 14/09/2014 16:58:46 +01:00

最佳答案

这是 GraphDiff 中的一个错误。用于附加父级导航属性的代码尚未准备好处理同一类型的多个父级。我刚刚在 develop 分支上用 pull request #102 修复了这个问题.

关于entity-framework - GraphDiff 和 EF6.1 – 递归多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25835344/

相关文章:

azure - 上传的图像在 azure 上发布后不显示

asp.net - 什么是 ASP.NET 迁移中的鉴别器列?

java - 为什么递归函数首先执行最后一部分?

c# - 使用 GraphDiff 更新多对多关联

c# - GraphDiff 也可以用于简单实体的部分更新吗?

entity-framework-6 - 具有断开连接的子实体的断开连接的复杂图

c# - 处理所有实现 IDisposable 的嵌套对象

c# - 使用 EntityFramework 删除单元格值

java - 合并排序中的递归 : two recursive calls

python - 在Python类中使用__iter__方法实现递归函数