EntityFramework CTP5 отслеживания изменений - PullRequest
1 голос
/ 11 февраля 2011

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

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" не создается.Я изменил свойства на virtual в объектах 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 вопроса.

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

Ответы [ 2 ]

1 голос
/ 11 февраля 2011

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

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

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

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

0 голосов
/ 01 мая 2012

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

...