我正在努力解决如何有效地构建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 :(得分:1)
Mate,你需要DbContext
喜欢餐馆里的服务员。
如果你在一家餐馆和10个朋友在一起,服务员不会接受第一个朋友的订单,然后 到厨房提供信息男人做饭,然后来回到第二个朋友再去直到厨房...... (如果这样做,请去另一家餐馆)。
服务员来到你的桌子并获得他需要的所有信息,然后去找男人做饭, 与DbContext相同,你可以添加尽可能多的新对象如你所愿,它会知道每个新对象,只要你初始化对象就不会抱怨。
和服务员一样,如果是一个好的服务员会知道他们有什么酒以及他能给你什么,如果你要求一些其他的葡萄酒,他可以从头开始告诉你#34;不,我们没有&#34 34;因为他是一个很好的服务员,总是知道他有什么。
为了使您的Dbcontext
变得更好Dbcontext
,您需要告诉她每个对象在那里期待什么。
离。初始化
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 !!!
编辑:
如果我的DbContext中有一个名为Lunch的实体,我可以执行以下操作:
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 ......时才会发生这一切。