데이터베이스에 대한 왕복 호출 수를 최소화 할 수 있도록 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);
}
먼저 메서드의 끝에서 한 번만 변경 저장을 호출해야하며 모델에서 속성을 초기화하여 null 참조를 피할 수 있습니다. –
null 참조에 대해 이야기하는 것이 아니며, 변경 사항을 커밋 할 때까지 컨텍스트에 항목이 없다는 것을 말하고 있습니다. – twilliams