2016-07-13 4 views
0

Я борюсь с тем, как эффективно структурировать мои запросы LINQ, чтобы я мог минимизировать количество обращений в оба конца в базу данных.Необходим более эффективный способ создания множества объектов

С помощью текущего кода, приведенного ниже, каждое из этих объектов может создавать множество открытых и закрытых соединений с базой данных.

Как можно частично изменить этот код для минимизации вызовов в базу данных и вставить больше объектов в отдельные вызовы?

Я также прибегал к вызову SaveChanges несколько раз, делаю проблемы с объектами, не существующими в контексте, пока не сохраню изменения.

public IActionResult AddSnapshots([FromBody]List<MembershipSnapshot> snapshots, bool? update = false) 
     { 
      if (!ModelState.IsValid) { return new BadRequestObjectResult(ModelState); } 
      if (snapshots.Count == 0) 
      { 
       ModelState.AddModelError("Empty", "There were no records provided to be inserted."); 
       return new BadRequestObjectResult(ModelState); 
      } 

      // Get the composite keys from the supplied list 
      var snapshotKeys = snapshots.Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray(); 
      // Find which records already exist in the database, pulling their composite keys 
      var snapshotsInDb = platformContext.MembershipSnapshots.Where(s => snapshotKeys.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate })) 
               .Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray(); 
      // And filter them out, so we remain with the ones that don't yet exist 
      var addSnapshots = snapshots.Where(s => !snapshotsInDb.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate })) 
       .ToList(); 
      platformContext.MembershipSnapshots.AddRange(addSnapshots); 
      platformContext.SaveChanges(); 

      // In addition to adding all of the snapshots that didn't exist, we'll populate the 
      // membership categories, aggregates and aggregate collections if they don't already exist 
      var aggregates = snapshots.Select(s => new { Name = s.Aggregate, Category = s.AggregateCategory }).Distinct(); 

      var addAggregates = aggregates.Where(a => !platformContext.MembershipAggregates.Any(ma => ma.Name == a.Name)) 
              .GroupBy(a => a.Name).Select(g => g.First()) 
              .Select(a => new Aggregate { Name = a.Name }); 
      platformContext.AddRange(addAggregates); 
      platformContext.SaveChanges(); 

      var addCategories = aggregates.Where(a => !platformContext.MembershipCategories.Any(c => c.Name == a.Category)) 
              .GroupBy(a => a.Category).Select(g => g.First()) 
              .Select(a => new Category { Name = a.Category }); 
      platformContext.AddRange(addCategories); 
      platformContext.SaveChanges(); 

      var addAggregateCollection = aggregates.Where(a => !platformContext.AggregateCollections.Any(ma => ma.Name == a.Name)) 
                .GroupBy(a => a.Name).Select(g => g.First()) 
                .Select(a => new AggregateCollection() 
                { 
                 Name = a.Name, 
                 Category = platformContext.MembershipCategories.Where(c => c.Name == a.Category).Single(), 
                 Description = a.Name, 
                 AggregateCollectionAggregates = new List<AggregateCollectionAggregate>() 
                 { 
                  new AggregateCollectionAggregate() 
                  { 
                   Aggregate = platformContext.MembershipAggregates.Where(ma => ma.Name == a.Name).Single() 
                  } 
                 } 
                }); 
      platformContext.AddRange(addAggregateCollection); 
      platformContext.SaveChanges(); 

      return new StatusCodeResult(StatusCodes.Status200OK); 
     } 
+0

Прежде всего вам нужно вызвать Сохранение изменений только один раз в конце метода, и вы можете избежать нулевой ссылки, инициализируя свойства из модели. –

+0

Я не говорю о нулевой ссылке, я говорю о каких-либо элементах, существующих в контексте, пока не зафиксирую изменения. – twilliams

ответ

1

Mate, что вам нужно, что в DbContext как к официанта в ресторане.

Если вы с 10 друзьями в ресторане, официант не идет принимая заказ первого друга, то собирается на кухню, чтобы дать информацию к человеку повару, затем приходит назад для второго друга Перейти снова до кухни ... (если делает так, пожалуйста, перейдите в другой ресторан).

официант подходит к столу и получить всю информацию ему нужно, а затем собираетесь на человек повар, же с DbContext, вы можете добавить много новых объектов, как вы хотите, он будет знать о каждом новый объект и не будет жаловаться до тех пор, пока вы инициализируете объекты.

Как и официант, если хороший официант узнает, какое вино у них есть и что он может вам дать, если вы попросите другое вино, он может сказать вам с самого начала: «Нет, у нас нет», потому что он хороший официант и всегда знает, что у него есть или нет. Для того, чтобы ваш Dbcontext был хорошим Dbcontext, вам нужно рассказать ей о каждом объекте, чего ожидать от него.

ex. от инициализации

public class Lunch 
    { 
     public IEnumerable<Meat> Meat { get; set; } = new List<Meat>(); 
     public Desert Desert { get; set; } = new Desert(); 
     public DateTime DateTime { get; set; } = DateTime.Now; 
     public bool WaiterIsFriendly { get; set; } = true; 
    } 

Надеюсь, что вы не знаете, как работать с DbContext !!!

Edit:

Если у меня есть Entity в моем DbContext имени обед, я могу сделать следующие:

var lunch1=new Lunch(); 
Context.Lunch.Add(lunch1); 
    lunch1.Desert=new Desert(); 
    lunch1.Meat.add(new Meat()); 

    var lunch2=new Lunch(); 
Context.Lunch.Add(lunch2); 
    lunch2.Desert=new Desert(); 
    lunch2.Meat.add(new Meat()); 

и в конце концов я могу сказать Context.SaveChanges();

Все это может произойти, только если я инициализирую Desert, Meat ... в классе Lunch.

+0

up для творческого примера =) – Progressive

+0

Я действительно не знаю, что этот ответ приводит к таблице. Я понимаю, как использовать DbContext.То, что вы не понимаете, заключается в том, что когда я добавляю свои вновь созданные объекты в контекст с помощью AddRange, они недоступны для доступа другим кодом ... наборы данных пустые. Кроме того, это лишь часть проблемы. Даже с одним SaveChanges в контексте, если все остальное было правильным, база данных открывает и закрывает соединения для каждого отдельного объекта, добавленного через AddRange. Если я добавляю 200 объектов, база данных открывается и закрывается 200 раз моим текущим кодом. – twilliams

Смежные вопросы