2014-01-22 3 views
0

Мое приложение читает файл XML и создать PatientDto, который я использую в методе CreatePatient(PatientDto patient)Управление отдельностоящий объект с Entity Framework

Этот метод картыPatientDto к Patient и сохраняет его с Entity Framework. При отображении, я имею в виду создать новую 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; } 
} 

Diet имеет список Week, который имеет список Day, который имеет список Meal, который имеет список Ingredient.

Когда я создаю нового пациента, все объекты графика являются новыми (они должны храниться в базе данных) , но ингредиенты. Ингредиенты уже существуют в базе данных.

Из-за сопоставления все ингредиенты - это разные экземпляры (даже если они имеют одинаковое деловое значение. Это два ингредиента с одинаковым идентификатором имеют разные экземпляры).

И когда я исполню мой код, у меня есть исключение:

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. И это выглядит так, как вам нужно сделать цикл, чтобы сделать это для всех ваших entites в графе объектов. Вам следует сократить объем доступа к базе данных в этом случае, и, возможно, этот код поможет вам в этом направлении.

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

Смежные вопросы