2017-08-30 36 views
0

比方说,我有一个名为vw_Project的EF类,其中包含属性字符串ProjectTitle以及其他属性。我想运行一个高效的LINQ查询,它只查询结果中第一条记录的第一列(第一个“单元格”,类似于SqlCommand.ExecuteScalar)。我可能会写这样的事:实体框架 - 在查询单个列时,如何区分没有结果和NULL值的结果?

string projectTitle = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .Select(p => p.ProjectTitle) 
    .FirstOrDefault(); 

的问题是,我不能告诉我查询是否有任何结果,或者如果它只是一个得到的结果与该varchar列的NULL值。

我总是可以查询整个对象来做出决定,然后将ProjectTitle列提取到内存中的字符串变量中,但是我会查询一堆我不需要的列,这是一个糟糕的解决方案。这看起来像这样:

string projectTitle; 
vw_Project project = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .FirstOrDefault(); 

if (project != null) 
{ 
    projectTitle = project.ProjectTitle; 
} 
else 
{ 
    throw new Exception("Invalid Project ID"); 
} 

如何在不查询其他列或行的情况下做出此决定?

+0

我不认为底部的解决方案是“穷人”:除非您急切地在'Project'上加载集合,否则开销将很难被检测到。你应该结合'Where'和'FirstOrDefault',即'FirstOrDefault(p => p.ProjectID == projID)'。 – dasblinkenlight

+0

@dasblinkenlight'FirstOrDefault'的好建议 - 我会相应地更新我的答案。至于另一个建议从数据库中获取整个对象的解决方案,你是对的,在大多数情况下它不会产生巨大的影响。但是,如果它是一个大型表格,尤其是一个具有计算列的表格,或者如果您需要获取多行而不是一个,那么这是一个不应该被遗忘的重要优化。 –

回答

2

如果您仅使用所需属性创建内嵌匿名类型,则仍然可以确定是否获得零结果或获得NULL记录。

string projectTitle; 
var result = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .Select(p => new { p.ProjectTitle }) 
    .FirstOrDefault(); 

if (result != null) 
{ 
    projectTitle = result.ProjectTitle; 
} 
else 
{ 
    throw new Exception("Invalid Project ID"); 
} 

如果查询得到的结果,该result实例将不能为空,不管内部ProjectTitle属性是否为空。

+2

请注意'Take(1)'是多余的。 'FirstOrDefault'做同样的事情。 –

+0

@GertArnold你是对的。在我的回答和回应中纠正了它。 –