https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-3.0
在 Microsoft 文档示例中,.FirstOrDefaultAsync()
用于Detail
和 Delete
GET
;.FindAsync()
用于DeleteConfirmed
.
我想知道这是为什么?
最佳答案
根据reference source DbSet.Find如果已在 DbContext 中获取具有相同 keyValues 的对象,则不会访问数据库:
/// 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 询问提供者的接口(interface) IQueryable.GetProvider()
然后调用IQueryProvider.Execute(Expression)
获取表达式定义的数据。这将始终访问数据库。
假设您有学校和学生,这是一种简单的一对多关系。您还有一个更改学生数据的程序。
Student ChangeAddress(dbContext, int studentId, Address address);
Student ChangeSchool(dbContext, int studentId, int SchoolId);
您在程序中有这个,因为这些程序将检查更改的有效性,可能伊顿学生不允许住在牛津校区,并且可能有些学校只允许特定年龄的学生。
您有以下代码使用这些过程:
void ChangeStudent(int studentId, Address address, int schoolId)
{
using (var dbContext = new SchoolDbContext())
{
ChangeAddress(dbContext, studentId, address);
ChangeSchool(dbContext, studentId, 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
关于c# - 当我们在 Entity Framework Core 中拥有主键时,我们是否应该始终使用 .Find() 而不是 .FirstOrDefault() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58773913/