我想更新itemsToUpdate集合。 此集合已在查询中使用,因此已在上下文本地属性中跟踪生成的实体。
从itemsToUpdate集合覆盖context.items.Local属性的最有效方法是什么?
private async Task<IEnumerable<item>> GetitemsAsync(IEnumerable<item> itemIds)
{
return await context.items.Where(t => itemIds.Select(x => x.Id).Contains(t.Id)).ToListAsync();
}
public async Task Update(...)
{
// Update
var queryUpdateitems = await GetitemsAsync(itemsToUpdate);
bool canUpdate = queryUpdateitems.All(t => t.UserId == userId);
if (!canUpdate)
{
throw new NotAuthorizedException();
}
else
{
// update here the itemsToUpdate collection
}
context.SaveChangesAsync();
}
答案 0 :(得分:0)
在您的情况下,您知道必须更新所有这些项目,您只是想确保当前用户可以更新所有项目(通过比较Item.UserId
)。您可以查询数据库以获得检查结果,而不是从数据库中获取所有现有项目以进行检查,如果检查为真,则可以将更新发送到数据库。
var itemIds = itemsToUpdate.Select(x => x.Id).ToList();
var canUpdate = await db.Blogs.Where(b => itemIds.Contains(b.Id)).AllAsync(t => t.UserId == userId);
if (canUpdate)
{
db.UpdateRange(itemsToUpdate);
}
else
{
throw new NotSupportedException();
}
await db.SaveChangesAsync();
在这里,您必须首先列出itemIds,因为EF不能内联查询中的项目列表,否则将在客户端上进行评估。这意味着EF正在获取整个表格。您的GetitemsAsync
方法也是如此。它还查询整个表。考虑在该方法中本地创建itemIds。
在方法中传入List<int>
后,EF会很乐意在查询中内联它,并且查询canUpdate
它会向数据库发送单个查询并从数据库中获取true / false。然后您可以直接使用UpdateRange
,因为有跟踪记录。由于它不会从数据库中获取所有项目,因此它也会更快。