EF插入/更新导航属性与分配ID性能?

时间:2013-09-20 01:19:37

标签: c# sql-server entity-framework devart

我们假设我们有一个模型/数据库表,如下所示(不是很好,但适合我的问题)。让我们假设一部电影总是只有一个导演和一个制作人。

类型

  • 编号
  • 名称

体裁

  • 编号
  • 名称
  • GenreId
  • 类型(导航财产)

  • 编号
  • 名称
  • List<Movie>(导航财产)

生产者

  • 编号
  • 名称
  • List<Movie>(导航财产)

演员

  • 编号
  • 名称
  • List<Movie>(db中有很多表)(导航属性)

电影

  • 编号
  • 姓名
  • SubGenreId
  • DirectorId
  • ProducerId
  • List<Actor>(导航财产)
  • 导演(导航财产)
  • 制作人(导航财产)
  • SubGenre(导航财产)

MovieActors (表格)

  • MovieId
  • 的actorId

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

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

  • 的movieName
  • GenreName
  • SubGenreName
  • DirectorName
  • ProducerName
  • 列出ActorNames

我们还假设有数百万的导演/制片人/演员/电影(每张表中基本上都有大量数据),导演/制片人/演员/电影的名称是出于简单目的而独一无二的。所以逻辑是,如果SubGenre存在使用它,否则创建SubGenre记录。同样地查找是否存在类型,使用否则创建它。同样适用于导演,制片人和演员。

最后,问题是

  1. 其中哪一个更快,为什么? (或)即使考虑到数百万条记录,它们是否相同?
  2. 是否可能在Sql Server和Oracle之间进行更改? (使用oracle,我使用Devart作为提供者)
  3. 方法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(); 
            }
    

0 个答案:

没有答案