C# 实体框架-查询单个列时,如何区分无结果和具有空值的结果之间的差异?

C# 实体框架-查询单个列时,如何区分无结果和具有空值的结果之间的差异?,c#,entity-framework,linq,C#,Entity Framework,Linq,假设我在EF中有一个名为vw_Project的类,它的属性ProjectTitle类型为string,以及其他属性。我想运行一个高效的LINQ查询,它只查询结果中第一条记录的第一列(第一个“单元格”,类似于SqlCommand.ExecuteScalar)。我可以这样写: string projectTitle = context.vw_Projects .Where(p => p.ProjectID == projID) .Select(p => p.Project

假设我在EF中有一个名为
vw_Project
的类,它的属性
ProjectTitle
类型为string,以及其他属性。我想运行一个高效的LINQ查询,它只查询结果中第一条记录的第一列(第一个“单元格”,类似于
SqlCommand.ExecuteScalar
)。我可以这样写:

string projectTitle = context.vw_Projects
    .Where(p => p.ProjectID == projID)
    .Select(p => p.ProjectTitle)
    .FirstOrDefault();
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");
}
问题是,我无法判断我的查询是否得到了零个结果,或者它是否只得到了一个值为
NULL
varchar
列的结果

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

string projectTitle = context.vw_Projects
    .Where(p => p.ProjectID == projID)
    .Select(p => p.ProjectTitle)
    .FirstOrDefault();
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");
}

如何在不查询其他列或行的情况下进行此确定?

如果仅使用所需的属性创建一个内嵌匿名类型,则仍然可以确定是得到零结果还是
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
实例将不会为null,无论内部的
ProjectTitle
属性是否为null。

如果仅使用所需的属性创建一个内嵌匿名类型,您仍然可以确定是得到零结果还是
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
实例将不会为null,无论内部
ProjectTitle
属性是否为null。

请注意,
Take(1)
是多余的
FirstOrDefault
也做了同样的事情。@GertArnold你完全正确。刚刚在我的回答和回答中更正了它。请注意,
Take(1)
是多余的
FirstOrDefault
也做了同样的事情。@GertArnold你完全正确。只是在我的回答和回答中更正了它。我不认为最底层的解决方案是“糟糕的”:除非您急切地在
项目上加载集合,否则开销将很难检测出来。你应该把
Where
FirstOrDefault
结合起来,即
FirstOrDefault(p=>p.ProjectID==projID)
@dasblinken对
FirstOrDefault
有很好的建议-我会相应地更新我的答案。至于另一个建议从数据库获取整个对象的解决方案,您是对的,在大多数情况下,这不会产生很大的影响。但是如果它是一个大表,特别是一个有计算列的表,或者如果你需要得到几行而不是一行,那么这是一个重要的优化,不应该被忘记。我不认为最底层的解决方案是“糟糕的”:除非你急切地在
项目
上加载集合,否则开销将很难检测出来。你应该把
Where
FirstOrDefault
结合起来,即
FirstOrDefault(p=>p.ProjectID==projID)
@dasblinken对
FirstOrDefault
有很好的建议-我会相应地更新我的答案。至于另一个建议从数据库获取整个对象的解决方案,您是对的,在大多数情况下,这不会产生很大的影响。但是,如果它是一个大表,特别是一个有计算列的表,或者如果您需要得到多行而不是一行,那么这是一个重要的优化,不应该忘记。