EF Core 2.1 更新相关实体查询效率
EF Core 2.1 Updating related entites query efficiency
我有一个学生模型,其中我有 phone 个号码的列表,addresses.When 我更新学生相关数据(phone 和地址)需要更新.为此,我在我的学生控制器中编写了一个 PUT 操作。它工作正常,但我担心查询的效率。请检查代码并建议我即兴创作(如果有的话)。谢谢
public async Task<IActionResult> Put(long id, [FromBody] Student student)
{
var p = await _Context.Students
.Include(t => t.PhoneNumbers)
.Include(t => t.Addresses)
.SingleOrDefaultAsync(t => t.Id == id);
if (p == null)
{
return NotFound();
}
_Context.Entry(p).CurrentValues.SetValues(student);
#region PhoneNumber
var existingPhoneNumbers = p.PhoneNumbers.ToList();
foreach (var existingPhone in existingPhoneNumbers)
{
var phoneNumber = student.PhoneNumbers.SingleOrDefault(i => i.Id == existingPhone.Id);
if (phoneNumber != null)
_Context.Entry(existingPhone).CurrentValues.SetValues(phoneNumber);
else
_Context.Remove(existingPhone);
}
// add the new items
foreach (var phoneNumber in student.PhoneNumbers)
{
if (existingPhoneNumbers.All(i => i.Id != phoneNumber.Id))
{
p.PhoneNumbers.Add(phoneNumber);
}
}
#endregion
#region Address
var existingAddresses = p.Addresses.ToList();
foreach (var existingAddress in existingAddresses)
{
var address = student.Addresses.SingleOrDefault(i => i.Id == existingAddress.Id);
if (address != null)
_Context.Entry(existingAddress).CurrentValues.SetValues(address);
else
_Context.Remove(existingAddress);
}
// add the new items
foreach (var address in student.Addresses)
{
if (existingAddresses.All(i => i.Id != address.Id))
{
p.Addresses.Add(address);
}
}
#endregion
await _Context.SaveChangesAsync();
return NoContent();
}
搜索内存中的小集合通常不是您需要担心的事情。因此,如果一个 Student 有几十个或数百个地址,重复查找的意义不大,尤其是与写入数据库所需的时间相比。
如果你确实想优化,你可以将学生地址复制到字典中。像这样:
var existingAddresses = p.Addresses.ToList();
var studentAddresses = student.Addresses.ToDictionary(i => i.Id);
foreach (var existingAddress in existingAddresses)
{
if (studentAddresses.TryGetValue(existingAddress.Id, out Address address))
{
_Context.Entry(existingAddress).CurrentValues.SetValues(address);
}
else
{
_Context.Remove(existingAddress);
}
}
像这样查询内存中的集合:
var address = student.Addresses.SingleOrDefault(i => i.Id == existingAddress.Id);
将简单地迭代所有 student.Addresses 比较 ID。 Dictionary<> 就像一个索引,提供非常快速的查找。
我有一个学生模型,其中我有 phone 个号码的列表,addresses.When 我更新学生相关数据(phone 和地址)需要更新.为此,我在我的学生控制器中编写了一个 PUT 操作。它工作正常,但我担心查询的效率。请检查代码并建议我即兴创作(如果有的话)。谢谢
public async Task<IActionResult> Put(long id, [FromBody] Student student)
{
var p = await _Context.Students
.Include(t => t.PhoneNumbers)
.Include(t => t.Addresses)
.SingleOrDefaultAsync(t => t.Id == id);
if (p == null)
{
return NotFound();
}
_Context.Entry(p).CurrentValues.SetValues(student);
#region PhoneNumber
var existingPhoneNumbers = p.PhoneNumbers.ToList();
foreach (var existingPhone in existingPhoneNumbers)
{
var phoneNumber = student.PhoneNumbers.SingleOrDefault(i => i.Id == existingPhone.Id);
if (phoneNumber != null)
_Context.Entry(existingPhone).CurrentValues.SetValues(phoneNumber);
else
_Context.Remove(existingPhone);
}
// add the new items
foreach (var phoneNumber in student.PhoneNumbers)
{
if (existingPhoneNumbers.All(i => i.Id != phoneNumber.Id))
{
p.PhoneNumbers.Add(phoneNumber);
}
}
#endregion
#region Address
var existingAddresses = p.Addresses.ToList();
foreach (var existingAddress in existingAddresses)
{
var address = student.Addresses.SingleOrDefault(i => i.Id == existingAddress.Id);
if (address != null)
_Context.Entry(existingAddress).CurrentValues.SetValues(address);
else
_Context.Remove(existingAddress);
}
// add the new items
foreach (var address in student.Addresses)
{
if (existingAddresses.All(i => i.Id != address.Id))
{
p.Addresses.Add(address);
}
}
#endregion
await _Context.SaveChangesAsync();
return NoContent();
}
搜索内存中的小集合通常不是您需要担心的事情。因此,如果一个 Student 有几十个或数百个地址,重复查找的意义不大,尤其是与写入数据库所需的时间相比。
如果你确实想优化,你可以将学生地址复制到字典中。像这样:
var existingAddresses = p.Addresses.ToList();
var studentAddresses = student.Addresses.ToDictionary(i => i.Id);
foreach (var existingAddress in existingAddresses)
{
if (studentAddresses.TryGetValue(existingAddress.Id, out Address address))
{
_Context.Entry(existingAddress).CurrentValues.SetValues(address);
}
else
{
_Context.Remove(existingAddress);
}
}
像这样查询内存中的集合:
var address = student.Addresses.SingleOrDefault(i => i.Id == existingAddress.Id);
将简单地迭代所有 student.Addresses 比较 ID。 Dictionary<> 就像一个索引,提供非常快速的查找。