1

假设我们有一个如下所示的模型/数据库表(布局不好但符合我的问题)。我们还假设一部电影总是只有一位导演和一位制片人。

类型

  • ID
  • 姓名

子流派

  • ID
  • 姓名
  • 类型 ID
  • 类型(航海财产)

导向器

  • ID
  • 姓名
  • List<Movie>(航海财产)

制片人

  • ID
  • 姓名
  • List<Movie>(航海财产)

演员

  • ID
  • 姓名
  • List<Movie>(数据库中有许多表)(导航属性)

电影

  • ID
  • 姓名
  • 子流派 ID
  • 导演编号
  • 生产者 ID
  • List<Actor>(航海财产)
  • 董事(航海财产)
  • 生产者(航海财产)
  • 子类型(导航属性)

电影演员(表)

  • 电影编号
  • 演员 ID

现在,让我们假设,我们已经在数据层(所以除了 id 之外,不会对对象进行重大更改跟踪)。我们在电影对象中有需要持久化的数据。如果存在,则需要更新,如果没有插入。

发送到 DataLayer 的电影对象 (movieDTO)。

  • 电影名
  • 流派名称
  • 子流派名称
  • 董事姓名
  • 生产者名称
  • 列出 ActorNames

我们还假设有数以百万计的导演/制片人/演员/电影(基本上每个表中有大量数据),并且为了简单起见,导演/制片人/演员/电影的名称是唯一的。所以逻辑是,如果 SubGenre 存在就使用它,否则创建 SubGenre 记录。同样查找是否存在流派,否则使用它创建它。导演、制片人和演员也是如此。

最后,问题是

  1. 其中哪一个会更快,为什么?(或)即使考虑到数百万条记录,它们是否相同?
  2. Sql Server 和 Oracle 之间可能会发生变化吗?(对于 oracle,我使用 Devart 作为提供者)

方法一:

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(); 
        }

方法二:

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