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

먼저 메서드의 끝에서 한 번만 변경 저장을 호출해야하며 모델에서 속성을 초기화하여 null 참조를 피할 수 있습니다. –

+0

null 참조에 대해 이야기하는 것이 아니며, 변경 사항을 커밋 할 때까지 컨텍스트에 항목이 없다는 것을 말하고 있습니다. – twilliams

답변

1

메이트, 당신은 레스토랑에서 웨이터에 같은 DbContext에서 일해야합니다. 당신이 레스토랑에서 10 친구들과 경우

는 웨이터 하지 후, 남자 요리사에 대한 정보를 제공하기 위해 부엌으로을 진행 한 후, 첫 번째 친구의 순서를 복용 오는 오고있다 두 번째 친구를 위해 되돌아 간다 go 부엌까지 (그와 같으면 다른 레스토랑에 가라.

웨이터는 다음 테이블에 와서 그가 필요로하는 모든 정보를 얻을하고 당신은 각각에 대해 알게 될 것이다, 당신이 원하는만큼 많은 새로운 개체를 추가, 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와 함께 작업하는 방법을 undestand 희망!

편집 : 내 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 ...를 초기화하는 경우에만 발생할 수 있습니다.

+0

크리에이티브 예제 =) – Progressive

+0

이 대답이 무엇을 테이블에 가져다 주는지 정말로 모르겠습니다. DbContext를 사용하는 방법을 이해합니다.당신이 이해하지 못하는 것은 AddRange가있는 컨텍스트에 새로 생성 된 객체를 추가 할 때 다른 코드에서 액세스 할 수 없다는 것입니다. 데이터 세트가 비어 있습니다. 게다가 그것은 문제의 일부일뿐입니다. 컨텍스트에 하나의 SaveChanges가 있어도 다른 것이 맞다면 데이터베이스는 AddRange를 통해 추가 된 모든 단일 개체에 대한 연결을 열고 닫는 것입니다. 200 개의 객체를 추가하면 데이터베이스가 현재 코드로 200 번 열고 닫힙니다. – twilliams

관련 문제