2014-09-14 1 views
2

У меня возникла проблема с подключением GraphDiff объекта, который имеет рекурсивное отношение «многие ко многим». Я использую GraphDiff 2.0.1 и Entity Framework 6.1.1.GraphDiff и EF6.1 - Рекурсивное отношение «многие ко многим»

Прогма управляет рецептами, которые могут содержать 0-n RecipeLines, который содержит ссылку на другой рецепт, который является ComponentRecipe, и это имеет RecipeLines и т. Д.

Я передаю объект рецепта в репозиторий, который имеет 1 линию рецепта с объектом Рецепт на линии, указывающей на родительский объект и объект ComponentRecipe, указывающий на другой рецепт.

Когда GraphDiff присоединяет элемент, то прикрепленный элемент, который он возвращает, имеет 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); 

     } 
    } 

Repository

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 

ответ

2

Это была ошибка в GraphDiff. Код для прикрепления родительских свойств навигации не был готов для обработки нескольких родителей того же типа. Я только что зафиксировал это на ветке develop с pull request #102.