https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-3.0
在microsoft文档示例中,
.FirstOrDefaultAsync()
用在Detail
和Delete
GET
中;
.FindAsync()
中使用了DeleteConfirmed
。
我想知道为什么吗?
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-3.0
在microsoft文档示例中,
.FirstOrDefaultAsync()
用在Detail
和Delete
GET
中;
.FindAsync()
中使用了DeleteConfirmed
。
我想知道为什么吗?
如果已经在DbContext中获取了具有相同keyValues的对象,则根据reference source DbSet.Find将不会访问数据库:
/// Finds an entity with the given primary key values.
/// If an entity with the given primary key values exists in the context,then it is
/// returned immediately without making a request to the store.
public abstract object Find(params object[] keyValues);
FirstOrDefault,类似的函数将调用IQueryable.GetEnumerator()
,后者将向IQueryable询问提供者IQueryable.GetProvider()
的接口,然后调用IQueryProvider.Execute(Expression)
以获取由Expression定义的数据。
这将始终访问数据库。
假设您的学校与学生在一起,这是一种简单的一对多关系。您还具有更改学生数据的过程。
Student ChangeAddress(dbContext,int studentId,Address address);
Student ChangeSchool(dbContext,int SchoolId);
您有此程序,因为这些程序将检查更改的有效性,可能不允许Eton学生住在牛津校区,并且可能有些学校只允许特定年龄的学生。
您具有使用以下过程的以下代码:
void ChangeStudent(int studentId,Address address,int schoolId)
{
using (var dbContext = new SchoolDbContext())
{
ChangeAddress(dbContext,studentId,address);
ChangeSchool(dbContext,schoolId);
dbContext.SaveChanges();
}
}
如果Change ...函数将使用FirstOrDefault()
,那么您将丢失其他过程所做的更改。
但是,有时您希望能够重新获取数据库数据,例如,因为其他人可能已经更改了数据,或者您刚刚进行的某些更改是无效的
Student student = dbContext.Students.Find(10);
// let user change student attributes
...
bool changesAccepted = AskIfChangesOk();
if (!changesAccepted)
{ // Refetch the student.
// can't use Find,because that would give the changed Student
student = dbContext.Students.Where(s => s.Id == 10).FirstOrDefault();
}
// now use the refetched Student with the original data
,
我认为这是因为进行“删除”时,您不知道该项目是否存在,因此需要默认设置,以防找不到。
在执行DeleteConfirmed时,您知道带有id
的项目存在并且可以使用Find
。