Я недавно обновил с 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()
. Но есть (по крайней мере некоторые) ссылки загружены.
Я знаю, что это уже была огромная работа, но вы также можете изменить ее с dbfirst на codefirst (обычно генератор кода работает нормально, поэтому вам нужно только проверить, все ли все еще работает). Не могли бы вы разместить какой-нибудь код (класс фильма и запрос на получение данных)? – bubi
К сожалению, переход на codefirst не является вариантом. Запрос для извлечения данных уже показан. Заглянуть в окна «Locals» достаточно, чтобы увидеть, что 'movie.Genre' -' null'. Будет ли добавлен код для 'Movie' – KingKerosin
- это объект, хранящийся в таблице с правильным идентификатором Genre? –