2011-02-10 4 views
1

Я пытаюсь воспроизвести то же поведение, что и EntityObject, используя CTP5 DBContext для отслеживания изменений. Рассмотрим таблицы фильма и режиссера. Отношения - всего лишь 1 режиссер для фильма и нескольких фильмов для каждого режиссера.EntityFramework CTP5 отслеживание изменений

var movie = new Movie(); 
      movie.Name = "ABCD"; 
      ctx.Movies.Add(movie);//ctx.Movies.AddObject(movie); 
      movie.Director = new Director() { Name = "dir1" }; 
      var existingDirector = ctx.Directors.Where(a => a.Name == "dir2").FirstOrDefault(); 
      movie.Director = existingDirector; 
      ctx.SaveChanges(); 

Если я запускаю это, используя EntityObject, этот код будет создать новый директор «dir1», как изменения отслеживаются. Если я запустил этот код с использованием генератора CTP 5 DbContext, новый директор «dir1» не будет создан. Я изменил свойства как виртуальный в объектах Movie и Director. Ниже приведен код.

public partial class Director 
{ 
    public Director() 
    { 
     //this.Movies = new HashSet<Movie>(); 
    } 

    // Primitive properties 

    public virtual int DirectorId { get; set; } 
    public virtual string Name { get; set; } 

    // Navigation properties 

    public virtual ICollection<Movie> Movies { get; set; } 

} 
public partial class Movie 
{ 
    public Movie() 
    { 
     //this.Actors = new HashSet<Actor>(); 
    } 

    // Primitive properties 

    public virtual int MovieId { get; set; } 
    public virtual Nullable<int> DirectorId { get; set; } 
    public virtual string Name { get; set; } 

    // Navigation properties 

    public virtual Director Director { get; set; }  
} 

У меня есть 3 вопроса.

  • Я ничего не теряю здесь? Несмотря на то, что я сохранил «виртуальный» для каждого свойства, объект не отслеживается. Зачем?
  • Должен ли я писать логику «Фиксация ассоциации», как это было сделано в EF4 POCOs?
  • Если да, то почему код исправления ассоциации был удален в генераторе DbContext T4?

ответ

1

Конечно новый директор не спасутся, потому что вы изменили режиссер нового фильма к существующей в некоторый более поздний момент в коде, попробуйте это, и вы получите их обоих сохраняются в БД:

var movie = new Movie(); 
movie.Name = "ABCD"; 
ctx.Movies.Add(movie); 
movie.Director = new Director() { Name = "dir1" };  
//movie.Director = existingDirector; 
ctx.SaveChanges(); 

Вы можете написать свою собственную логику фиксации логики, но это поможет вам синхронизировать конечные точки ваших ассоциаций и не имеет никакого отношения к коду, который вы показали здесь.

Причина, по которой ваш код сохраняет нового директора в БД при использовании EntityObjects из-за концепции, которая называется Отношения отношения. Интервал отношений определяет, что ObjectContext автоматически присоединяет объект, когда вы подключили его к другому прикрепленному объекту. Если этот отдельный объект является новым, когда он привязан к контексту, его EntityState будет добавлен. Однако это поведение отношения отношения не реализовано даже при использовании прокси-серверов POCO (т. Е. Виртуальных свойств навигации).

+0

Код немой, но я хотел показать несоответствие между EntityObject и генераторами DbContext T4. Дело в том, что с генератором EntityObject тот же код (без комментирования строки) создает «dir1» в db, тогда как генератор POCO или DbContext этого не делает. Зачем? Что случилось с изменением отслеживания? – Jonna

+0

Прочтите обновленный ответ. –

0

Я думаю, причина в том, что это не работает так, как вы ожидаете, это то, что вы создаете экземпляр самого класса Movie (например, используя новый оператор), а не динамический прокси. Сам класс Movie не имеет встроенного отслеживания изменений. Следовательно, когда вы устанавливаете свойство Director, ни одно уведомление не отправляется в DbContext. Даже если вы добавили фильм в DbContext, вы все еще ссылаетесь на исходный объект, а не на прокси. Я думаю, если бы вы создали объект, используя DbSet.Create() (http://msdn.microsoft.com/en-us/library/gg696685(v=vs.103).aspx), это сработает.

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