1

以下のようなモデル/データベーステーブルがあると仮定しましょう(うまくレイアウトされていませんが、私の質問に適合します)。また、1 つの映画には常に 1 人の監督と 1 人のプロデューサーしかいないと仮定しましょう。

ジャンル

  • ID
  • 名前

サブジャンル

  • ID
  • 名前
  • ジャンルID
  • ジャンル(航海財産)

監督

  • ID
  • 名前
  • List<Movie>(航行財産)

プロデューサー

  • ID
  • 名前
  • List<Movie>(航行財産)

アクター

  • ID
  • 名前
  • List<Movie>(データベースに多対多テーブルがあります) (ナビゲーション プロパティ)

映画

  • ID
  • 名前
  • サブジャンルID
  • ディレクター ID
  • プロデューサー ID
  • List<Actor>(航行財産)
  • ディレクター(航海財産)
  • プロデューサー(航海財産)
  • SubGenre (ナビゲーション プロパティ)

MovieActors (テーブル)

  • ムービー ID
  • アクター ID

ここで、すでにデータ レイヤーにいると仮定しましょう (したがって、ID 以外のオブジェクトには主要な変更追跡はありません)。永続化する必要があるデータが movie オブジェクトにあります。存在する場合は更新する必要があり、挿入されていない場合は更新する必要があります。

DataLayer に送信されるムービー オブジェクト (movieDTO)。

  • ムービー名
  • ジャンル名
  • サブジャンル名
  • ディレクター名
  • プロデューサー名
  • ActorNames の一覧表示

また、何百万もの監督/プロデューサー/俳優/映画 (基本的に各テーブルには膨大な量のデータ) があり、簡単にするために監督/プロデューサー/俳優/映画の名前は一意であると仮定します。したがって、ロジックは、SubGenre が存在する場合はそれを使用し、そうでない場合は SubGenre レコードを作成します。同様に、Genre が存在する場合は探し、そうでない場合はそれを使用して作成します。監督、プロデューサー、俳優についても同様です。

最後に、質問は

  1. これらのうちどれがより高速で、その理由は何ですか? (または) 数百万のレコードを考慮しても同じですか?
  2. Sql Server と Oracle の間で変更される可能性はありますか? (オラクルでは、プロバイダーとして Devart を使用しています)

アプローチ 1:

using (MovieDBContext context = new MovieDBContext())
        {
            Movie movie;

            movie = context.Movies.Where(a => a.Name == movieDTO.MovieName).SingleOrDefault();
            if (movie == null)
                movie = new Movie() { Name = movieDTO.MovieName };

            var subGenre = context.SubGenres.Where(a => a.Name == movieDTO.SubGenreName).SingleOrDefault();
            if (subGenre == null)
            {
                movie.SubGenre = new SubGenre() { Name = movieDTO.SubGenreName };
                // Check if Genre exists.
                var genre = context.Genres.Where(a => a.Name == movieDTO.GenreName).SingleOrDefault();
                if (genre == null)
                {                        
                    movie.SubGenre.Genre = new Genre() { Name = movieDTO.GenreName };
                }
                else
                {
                    movie.SubGenre.Genre = genre;
                }
            }
            else
                movie.SubGenre = subGenre;


            var director = context.Directors.Where(a => a.Name == movieDTO.DirectorName).SingleOrDefault();
            if (director == null)
                movie.Director = new Director() { Name = movieDTO.DirectorName };
            else
                movie.Director = director;

            var producer = context.Producers.Where(a => a.Name == movieDTO.ProducerName).SingleOrDefault();
            if (producer == null)
                movie.Producer = new Producer() { Name = movieDTO.ProducerName };
            else
                movie.Producer = producer;

            // I am skipping the logic of deleting all the actors if the movie is existing. 
            foreach (var name in movieDTO.Actors)
            {
                var actor = context.Actors.Where(a => a.Name == name).SingleOrDefault();
                if (actor == null)
                    movie.Actors.Add(new Actor() { Name = name });
                else
                    movie.Actors.Add(actor);
            }                

            // Finally save changes. All the non-existing entities are added at once. 
            // EF is keeping track if the entity exists or not.
            context.SaveChanges(); 
        }

アプローチ 2:

using (MovieDBContext context = new MovieDBContext())
        {
            var genre = context.Genres.Where(a => a.Name == movieDTO.GenreName).SingleOrDefault();
            if (genre == null)
            {                      
                genre = new Genre() { Name = movieDTO.GenreName };
                context.Genres.Add(genre); // genre.Id is populated with the new id.
                context.SaveChanges();
            }

            var subGenre = context.SubGenre.Where(a => a.Name == movieDTO.SubGenreName).SingleOrDefault();
            if (subGenre == null)
            {
                subGenre = new SubGenre() { Name = movieDTO.SubGenreName };
                context.SubGenres.Add(subGenre); // subGenre.Id is populated with the new id.
                context.SaveChanges();
            }

            var director = context.Directors.Where(a => a.Name == movieDTO.DirectorName).SingleOrDefault();
            if (director == null)
            {
                director = new Director() { Name = movieDTO.DirectorName };
                context.Directors.Add(director); // director.Id is populated with the new id.
                context.SaveChanges();
            }

            var producer = context.Producers.Where(a => a.Name == movieDTO.ProducerName).SingleOrDefault();
            if (producer == null)
            {
                producer = new Producer() { Name = movieDTO.ProducerName };
                context.Producers.Add(producer); // director.Id is populated with the new id.
                context.SaveChanges();
            }

            // Similarly for actors, add them if they don't exist.
            foreach (var name in movieDTO.Actors)
            {
                var actor = new Actor() { Name = movieDTO.name };
                context.Actors.Add(actor); 
                context.SaveChanges();
            }       

            // Lastly movie.
            Movie movie = context.Movies.Where(a => a.Name == movieDTO.MovieName).SingleOrDefault();
            if (movie == null)
            {
                movie = new Movie() { Name = movieDTO.MovieName };
            }
            // This works for update as well.

            // The id's are added/updated instead of actual entities.
            movie.DirectorId = director.Id; 
            movie.SubGenreId = subGenre.Id; 
            movie.ProducerId = producer.Id;

            // I am skipping the logic of deleting all the actors if the movie is existing. 
            foreach (var name in movieDTO.Actors)
            {
                var actor = context.Actors.Where(a => a.Name == name).SingleOrDefault(); // Actors always exist now because we added them above.
                movie.Actors.Add(actor);
            }                

            // Finally save changes. Here only Movie object is saved as all other objects are saved earlier.
            context.SaveChanges(); 
        }
4

0 に答える 0