2015-11-20 2 views
1

Я недавно обновил с EF4 до EF6 (сначала по базе данных). После многих изменений здесь и там все выглядит как работа снова, как и раньше.После обновления EntityFramework некоторая ссылка внешнего ключа больше не загружается

К сожалению, теперь я столкнулся с действительно переработанной проблемой.

У меня есть три простых стола (Movie, Director, Genre). Каждый из них имеет уникальный ключ (Id) типа Guid.

В фильме есть два внешних ключа. От одного до Director, от одного до Genre.

Теперь, добавив новый фильм (режиссер и жанр уже существующий)

var movie = new Movie 
{ 
    Name = "The Hobbit", 
    DirectorId = Guid.Parse("c3c7606d-35f8-4de4-b7af-89ab19761dc4"), 
    GenreId = Guid.Parse("e19e304e-2567-4771-b842-962c067b5565") 
}; 

dbContext.Movie.Add(movie); 
dbContext.SaveChanges(); 

Как приходить из EF4, отложенная загрузка разрешена.

При проверке movie.Director я получаю правильный Director -entity. Однако movie.Genre всегда null.

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

Сторона примечания: Это просто упрощенный пример. Реальный проект имеет более 80 таблиц с гораздо большим количеством отношений.

Редактировать # 1

Классы Movie, Genre и Director

public partial class Movie 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Movie() 
    { 
    } 

    public System.Guid Id { get; set; } 
    public string Name { get; set; } 
    public System.Guid DirectorId { get; set; } 
    public System.Guid GenreId { get; set; } 

    public virtual Director Director { get; set; } 
    public virtual Genre Genre { get; set; } 
} 

public partial class Director 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Director() 
    { 
     this.Movie = new HashSet<Movie>(); 
    } 

    public System.Guid Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<Movie> Movie { get; set; } 
} 

public partial class Genre 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Genre() 
    { 
     this.Movie = new HashSet<Movie>(); 
    } 

    public System.Guid Id { get; set; } 
    public string Name { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<Movie> Movie { get; set; } 
} 

Зв Нет ничего особенного в сгенерированном коде.

Edit # 2 (@gabriel комментарий)

var moviedId = Guid.Parse("de0eca49-eae7-4583-b2e7-0003c148db99"); 
var theMovie = dbContext.Movie.Single(m => m.Id == moviedId); 
var theMovieInclude = dbContext.Movie.Include(m => m.Genre).Single(m => m.Id == moviedId); 

Оба объекта имеет свойство загруженное правильно.

Edit # 3

при использовании

var movie = dbContext.Set<Movie>().Create(); 

movie.Name = "The Hobbit"; 
movie.DirectorId = Guid.Parse("c3c7606d-35f8-4de4-b7af-89ab19761dc4"); 
movie.GenreId = Guid.Parse("e19e304e-2567-4771-b842-962c067b5565"); 

dbContext.Movie.Add(movie); 
dbContext.SaveChanges(); 

вместо movie.Genre теперь правильно.

Я не понимаю, почему movie.Director установлен с использованием new Movie(), но movie.Genre нет. Может ли кто-нибудь объяснить это?

В моем понимании (как объясняется в вопросе this), никакие ссылки не должны быть загружены до тех пор, пока не будет установлено при использовании new Movie() вместо dbContext.Set<Movie>().Create(). Но есть (по крайней мере некоторые) ссылки загружены.

+0

Я знаю, что это уже была огромная работа, но вы также можете изменить ее с dbfirst на codefirst (обычно генератор кода работает нормально, поэтому вам нужно только проверить, все ли все еще работает). Не могли бы вы разместить какой-нибудь код (класс фильма и запрос на получение данных)? – bubi

+0

К сожалению, переход на codefirst не является вариантом. Запрос для извлечения данных уже показан. Заглянуть в окна «Locals» достаточно, чтобы увидеть, что 'movie.Genre' -' null'. Будет ли добавлен код для 'Movie' – KingKerosin

+0

- это объект, хранящийся в таблице с правильным идентификатором Genre? –

ответ

0

Найдено вопрос: Где-то раньше, в контексте данного вопроса (вопрос был просто упрощенный пример), связанная с этим Genre -логического объекта уже загружены в dbContext, например, для получения идентификатора для имени «Ужас».

При этом этот Genre будет отображаться на новый Movie, поскольку он уже существует/загружен в dbContext.

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