Entity Framework POCO с внешними ключами - PullRequest
1 голос
/ 12 ноября 2010

Мой вопрос лучше объяснить с помощью примера кода. Я использую POCO с прокси-серверами отслеживания изменений, которые генерируются генератором POCO C # по умолчанию. Пожалуйста, смотрите ниже.

Предположим, у вас есть Movie, MusicDirector и Director в базе данных, и отношения между ними - это Director, а MusicDirector может управлять несколькими фильмами, а фильм может иметь только одного Director и MusicDirector. Так как я новый пользователь и не могу публиковать изображения, вот моя структура БД.

Таблица фильмов имеет MovieId, Name, MusicDirectorId, DirectorId

Таблица директоров имеет DirectorId, Имя

Таблица MusicDirector имеет идентификатор MusicDirector, имя

Вот ссылка на диаграмму. http://i.stack.imgur.com/ce49r.png.

Я пытаюсь вставить новый фильм, а режиссер и музыкальный директор «уже существует» в БД. Ниже мой код.

Movie movie = new Movie();            
        movie.Name = "Movie1";
        movie.Director = new Director() { Name = "DirectorA" };           
        movie.MusicDirector = new MusicDirector() { Name = "MusicDirectorA" };

        using (TestEFEntities ctx = new TestEFEntities())
        {
            movie.Director = ctx.Directors.Where(x => x.Name == movie.Director.Name).FirstOrDefault();
            movie.MusicDirector = ctx.MusicDirectors.Where(x => x.Name == movie.MusicDirector.Name).FirstOrDefault();                                    
            ctx.Movies.AddObject(movie);                    
            ctx.SaveChanges();
        }

Теперь, когда я делаю это, запись MusicDirector снова добавляется, даже если она перезаписывается записью из БД. Вы можете подумать, почему я сохраняю эту строку movie.Director = new Director () {Name = "DirectorA"}; изначально это приложение Asp.net MVC, в котором объект Movie связан с именами режиссера и musicdirector, которые добавляет пользователь. Итак, первые 4 строки неявно выполняются MVC и думают, что все остальные строки находятся на уровне сервиса. Я что-то упускаю, так как это очень простой сценарий, и фреймворк должен с этим справиться? Конечно, одним из решений этой проблемы является создание нового объекта Movie и назначение записей из базы данных, что я не хочу делать, поскольку мне нужно скопировать все свойства из объекта фильма, отправленного контроллером. Как я могу решить эту проблему?

Кроме того, это работает правильно в Self-Tracking Entities. Является ли это своего рода ограничением для POCO, и было бы здорово, если бы кто-то мог объяснить поведение?

1 Ответ

0 голосов
/ 12 ноября 2010

Если вы используете POCO, ваш код должен работать так, как вы ожидали.Кроме того, вы можете попытаться заполнить FK вместо назначения целого объекта следующим образом:

using (TestEFEntities ctx = new TestEFEntities())
{
    movie.DirectorID = ctx.Directors
        .Where(x => x.Name == movie.Director.Name).First().DirectorID;

    movie.MusicDirectorID = ctx.MusicDirectors
        .Where(x => x.Name == movie.MusicDirector.Name).First().MusicDirectorID;

    ctx.Movies.AddObject(movie);                    
    ctx.SaveChanges();
}
...