我是Linq和Entity Framework的新手,并且在此查询中收到空引用异常:
using (var db = new PhoenixContext())
{
tblCustomer cust = (from c in db.tblCustomer
where c.CustomerID == _CustomerID
select c).FirstOrDefault();
string altPhone;
altPhone = cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone.Where(p => p.PhoneTypeID == 2).FirstOrDefault().Phone;
)
tblCustomerContactInformationPhone中有一行。 Where子句应该删除它,我应该得到一个空字符串。但是,我得到了:
Object reference not set to an instance of an object.
我做错了什么,如何正确执行此操作以便将空结果集正确转换为空字符串?
链接的问题没有帮助,因为这是Linq的使用特有的,这个问题没有涵盖。 @ evanmcdonnal的回答非常有帮助,并解决了我的问题。
答案 0 :(得分:2)
这可能会被关闭,因为你的问题重复了之前被问过的1000000000000个其他NullReferenceException问题。
想想这个.Where(p => p.PhoneTypeID == 2).FirstOrDefault().Phone
如果tblCustomerContactInformationPhone
中PhoneTypeID
的{{1}}项中没有项目,会发生什么? FirstOrDefault为您提供'default',在这种情况下为null
,然后您执行TheValueRetuendFromFirstOrDefaultWhichIsNull.Phone
并获得NullReferenceException。
而是将其分成两行。
string phone = String.Empty;
var temp = cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone.Where(p => p.PhoneTypeID == 2).FirstOrDefault();
if (temp != null)
phone = temp.Phone;
编辑:另一种选择是使用select来获取Phone
的值,以便您可以像尝试一样使用空合并运算符。这看起来像这样;
var phone = cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone.Where(p => p.PhoneTypeID == 2).Select(x => x.Phone).FirstOrDefault() ?? String.Empty;
这样可以正常工作,因为select中的lambda表达式将应用于0个元素,如果where不返回任何元素,那么你最终只能从FirstOrDefault返回null,在这种情况下你将获取空字符串。
答案 1 :(得分:1)
在本条款中:
cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone.Where(p => p.PhoneTypeID == 2).FirstOrDefault().Phone ?? String.Empty;
您正在访问可能为空的引用的Phone
属性。
您可以执行以下操作:
var contactinfo = cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone.FirstOrDefault(p => p.PhoneTypeID == 2);
if(contactinfo != null){
Console.Write(contactinfo.Phone);
}
答案 2 :(得分:1)
很可能没有任何条目符合您的PhoneTypeID == 2
条件,因此.FirstOrDefault()
会返回null
。尝试访问.Phone
属性会引发空引用异常。
其他答案表明您可以对.FirstOrDefault()
的结果进行空值检查,但是您可以使用Entity Framework的另一个技巧来查询Phone
属性,并避免选择比您需要的更多数据:
altPhone = cust.tblCustomerContactInformation1.tblCustomerContactInformationPhone
.Where(p => p.PhoneTypeID == 2)
.Select(p => p.Phone)
.FirstOrDefault() ?? "";
这是有效的,因为SQL Server在运行为空值时不会抛出异常,而是传播空值。
答案 3 :(得分:0)
当您使用FirstOrDefault
时,tblCustomerContactInformationPhone
的“默认”值为null
。如果该表的查询没有找到任何内容(意味着没有符合2的PhoneTypeID
的记录),您将获得null
,并且在您的代码中,您试图获得{{1} } Phone
。你的null
在这里毫无用处。