C# 实体框架 - 在使用之前检查单个记录的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2142597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework - Correct way to check for single records before using them
提问by Keith Barrows
To get a LIST of records I normally do something along the lines of:
为了获得记录列表,我通常会按照以下方式做一些事情:
var efCompany = from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a;
To get a single record, when I know I am using the PK to retrieve it, I use something like:
为了获得单个记录,当我知道我正在使用 PK 来检索它时,我使用类似的东西:
var efCompany = (from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a).First();
Now, using the single record approach, if the PK is a faulty value (like it purposefully is in testing) the 2nd line throws an error.
现在,使用单记录方法,如果 PK 是错误值(就像它故意在测试中一样),第二行会引发错误。
What is the best practiceway of getting a single record and dealing with it?
获取单个记录并处理它的最佳实践方法是什么?
采纳答案by Jon Skeet
Use SingleOrDefault
if you expect 0 or 1, or FirstOrDefault
if you just need the first record out of potentially many, but can cope with 0. Both will return the default value for the type (usually null) if there are no results.
使用SingleOrDefault
,如果你希望为0或1,或者FirstOrDefault
如果你只需要在第一个记录了许多潜在的,但可以用0两种应对将返回类型(通常为空)的默认值,如果没有结果。
By the way, queries like this are generally more readable (IMO) withoutusing a query expression, so you might have something like:
顺便说一句,像这样的查询通常在不使用查询表达式的情况下更具可读性(IMO),因此您可能会遇到以下情况:
var efCompany = _dbRiv.Company
.Where(a => a.CompanyId == companyFeedInfo.CompanyId)
.SingleOrDefault();
if (efCompany != null)
{
// Use it
}
else
{
// Report to user, or whatever
}
Query expressions are great when you're using multiple operators, or doing relatively complex things like joins - but if you've justgot a where
clause or justgot a projection, this "dot notation" is simpler IMO. It also works better when you need to call a method like FirstOrDefault
at the end.
当您使用多个运算符或执行诸如连接之类的相对复杂的事情时,查询表达式非常有用 - 但如果您只有一个where
子句或只有一个投影,则这种“点表示法”在 IMO 中更简单。当您需要调用像FirstOrDefault
最后这样的方法时,它也能更好地工作。
回答by Franci Penov
Note that both SingleOrDefault()
and FirstOrDefault()
will not allow you to specify the default value.
请注意这两个SingleOrDefault()
和 FirstOrDefault()
不会允许你指定的默认值。
There's DefaultIfEmpty()
, which allows you to specify the default value you want returned if there are no items in the enumerable. You can combine this one with First()
(as in DefaultIfEmpty().First()
) to achieve FirstOrDefault()
-like behavior and a lambda to wrap creating a new instance and adding it to the set.
有DefaultIfEmpty()
,它允许您指定在可枚举项中没有项目时要返回的默认值。您可以将此与First()
(如 in DefaultIfEmpty().First()
)结合以实现FirstOrDefault()
类似行为,并使用 lambda 来包装创建新实例并将其添加到集合中。
If you just need to check for the existence of a record, you can also use Any()
. However, this will result in two queries, if you need to process the record if it exists.
如果您只需要检查记录是否存在,也可以使用Any()
. 但是,这将导致两个查询,如果您需要处理该记录(如果它存在)。
回答by kazem
var efCompany = _dbRiv.Company
.SingleOrDefault(a => a.CompanyId == companyFeedInfo.CompanyId);
if (efCompany != null)
{
// Use it
}
else
{
// Report to user, or whatever
}
回答by Jake Steele
You can also use
你也可以使用
_dbRiv.Company.find(#id)
if you are looking for a record without its included models.
如果您正在寻找没有包含模型的记录。
Or
或者
_dbRiv.Company.FirstOrDefault(x => x.Id == #id);
I recommend FirstOrDefault over SingleOrDefault because of the performance. With SingleOrDefault it needs to scan the entire table and make sure there is only one record with the Id. With FirstOrDefault it can simply go until it finds that id then stop. On a large table it will save you small amounts of time with each query.
由于性能,我推荐 FirstOrDefault 而不是 SingleOrDefault。使用 SingleOrDefault 它需要扫描整个表并确保只有一条记录带有 Id。使用 FirstOrDefault,它可以简单地运行,直到找到该 id 然后停止。在大表上,每次查询都会为您节省少量时间。
Also you can use AsNoTracking to improve memory consumption if you don't need to track any changes made to the model. For instance if you are returning it via a rest request without calling save.
如果您不需要跟踪对模型所做的任何更改,您也可以使用 AsNoTracking 来改善内存消耗。例如,如果您通过休息请求返回它而不调用保存。