entity framework – 在使用之前检查单个记录的正确方法
要获得记录列表,我通常会做以下事情:
var efCompany = from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a;
要获得单个记录,当我知道我正在使用PK来检索它时,我会使用以下内容:
var efCompany = (from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a).First();
现在,使用单记录方法,如果PK是一个错误的值(就像它有目的地在测试中),第二行会抛出错误。
获得单个记录并处理它的最佳实践方法是什么?
如果您期望0或1,请使用SingleOrDefault
,如果您只需要第一个记录,则使用SingleOrDefault
,但可以应对0.如果没有结果,两者都将返回该类型的默认值(通常为null)。
顺便说一下,这样的查询通常更具可读性(IMO) 而不使用查询表达式,所以你可能会有类似的东西:
var efCompany = _dbRiv.Company .Where(a => a.CompanyId == companyFeedInfo.CompanyId) .SingleOrDefault(); if (efCompany != null) { // Use it } else { // Report to user, or whatever }
当您使用多个运算符或执行相对复杂的事情(如连接)时,查询表达式很棒 – 但如果您刚刚获得了where
子句或只是进行了投影,那么这个“点符号”就更简单了。 当你需要在最后调用类似FirstOrDefault
的方法时,它也会更好。
请注意, SingleOrDefault()
和FirstOrDefault()
都不允许您指定默认值。
有DefaultIfEmpty()
,它允许您指定在枚举中没有项目时返回的默认值。 您可以将这一个与First()
(如在DefaultIfEmpty().First()
)组合以实现FirstOrDefault()
的行为,并使用lambda来创建新实例并将其添加到集合中。
如果您只需要检查是否存在记录,也可以使用Any()
。 但是,如果您需要处理记录(如果存在),这将导致两个查询。
var efCompany = _dbRiv.Company .SingleOrDefault(a => a.CompanyId == companyFeedInfo.CompanyId); if (efCompany != null) { // Use it } else { // Report to user, or whatever }
你也可以使用
_dbRiv.Company.find(#id)
如果您正在寻找没有其包含型号的记录。
要么
_dbRiv.Company.FirstOrDefault(x => x.Id == #id);
由于性能的原因,我推荐FirstOrDefault优于SingleOrDefault。 使用SingleOrDefault,它需要扫描整个表并确保只有一个带有Id的记录。 使用FirstOrDefault,它可以直到找到id然后停止。 在大型表格上,每次查询都会为您节省少量时间。
如果您不需要跟踪对模型所做的任何更改,也可以使用AsNoTracking来提高内存消耗。 例如,如果您通过rest请求返回它而不调用save。