Ich habe Probleme damit, meine LINQ-Abfragen effizient zu strukturieren, so dass ich die Anzahl der Roundtrip-Aufrufe an die Datenbank minimieren kann.Benötigen Sie eine effizientere Möglichkeit, viele Entitäten zu erstellen
Mit dem aktuellen Code unten kann jede dieser Objektkreationen zahlreiche offene und geschlossene Datenbankverbindungen erzeugen.
Wie könnte ein Teil dieses Codes neu strukturiert werden, um die Aufrufe an die Datenbank zu minimieren und mehr Objekte in einzelne Aufrufe einzufügen?
Ich habe auch mehrmals auf SaveChanges aufgerufen, um Probleme von Objekten, die nicht im Kontext vorhanden sind, zu tun, bis ich die Änderungen speichere.
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);
}
Zunächst müssen Sie Änderungen nur einmal am Ende der Methode speichern, und Sie können NULL-Referenz vermeiden, indem Sie die Eigenschaften aus dem Modell initialisieren. –
Ich spreche nicht über Null-Referenz, ich spreche über keine Elemente in dem Kontext, bis ich die Änderungen festschreibe. – twilliams