2014-01-22 59 views
0

我的應用程序讀取XML文件,並創建一個PatientDto,我的方法CreatePatient(PatientDto patient)管理分離的實體與實體框架

這種方法映射PatientDtoPatient與實體框架將其存儲使用。通過映射,我的意思是創建一個新的Patient與這名患者被寫如下的PatientDto

值:

public class PatientDto 
{ 
    public string Name { get; set; } 
    public IEnumerable<DietDto> Diets { get; set; } 
} 

internal class Patient 
{ 
    public Patient(PatientDto dto) 
    { 
     this.Name = dto.Name; 
     this.Diets = this.BuildDiets(dto.Diets); 
    } 
    public string Name { get; set; } 
    public IEnumerable<Diet> Diets { get; set; } 
} 

一個DietWeek列表,有Day列表,具有列表Meal,它有一個Ingredient的列表。

當我創建新的患者,圖形的所有對象都是新的(這是他們應該被存儲在數據庫中)的成分。成分已經存在於數據庫中。

由於映射,所有的成分都是不同的實例(即使它們具有相同的業務含義,這是具有相同ID的兩種成分具有不同實例)。

當我執行我的代碼,我有一個例外:

A duplicate value cannot be inserted into a unique index. [ Table name = Ingredients,Constraint name = PK_dbo.Ingredients ] 

速戰速決,我發現這是一個:

foreach (var diet in patient.Diets) 
    foreach (var week in diet.Weeks) 
     foreach (var day in week.Days) 
      foreach (var recipe in day.Meals) 
       for (int i = 0; i < recipe.Recipe.Ingredients.Count; i++) 
       { 
        recipe.Recipe.Ingredients[i] = (from igt in this.Context.Ingredients 
                where igt.Id == recipe.Recipe.Ingredients[i].Id 
                select igt).Single(); 
       } 

但是,這不是真正可讀一個循環中的一個循環,在...中不是我所稱的優化代碼。

有沒有其他的方法可以正確地做到這一點?

回答

0

您必須使用EF上下文中retreived的實際Ingredient對象正確更新數據庫。看起來你需要做一些循環來完成對象圖中的所有實體。你應該做的是在這種情況下減少數據庫訪問的數量,也許這個代碼會幫助你朝這個方向發展。

var ingredientIds = recipe.Recipe.Ingredients.Select(ingredient => ingredient.Id).ToList(); 
List<Ingredients> dbIngredients = this.Context.Ingredients.Where(ingredient => ingredientIds.Contains(ingredient.Id)).ToList(); 
recipe.Recipe.Ingredients = dbIngredients; 

而且任何人只要有更新與EF對象圖掙扎和相關實體也應該檢查出GraphDiff