"可空对象必须具有值QUOT;非原始/非结构对象上检查空后异常

问题描述:

我收到可空对象必须检查空常规对象后有一个值,空检查后。我发现各种问题,主要是对LINQ到SQL,有相同的问题,但始终为空的基本类型(如布尔?日期时间

I'm getting Nullable object must have a value after checking for null on a regular object, after a null check. I've found various questions, mostly regarding linq-to-sql, having the same problem but always with nullable primitive types (as in bool? or DateTime?).

引起我的情况异常的行看起来是这样的:

The line causing the exception in my case looks like this:

myDataContext.Orders.Where(y => customer.Address == null || (string.IsNullOrEmpty(customer.Address.Street) || y.Customers.Addresses.Street == customer.Address.Street)))

客户类看起来是这样的:

public class Customer
{
    private Address address = null;
    public Address Address{get{return address;} set{address=value;}}
}

地址属性看起来是这样的:

address property looks like this:

public class Address
{
    private string street = null;
    public string Street{get{return street ;} set{street =value;}}
}

如果我更换上面这行代码:

If I replace above code line with this:

string custStreet = null;
if (customer.Address != null)
{
    custStreet = customer.Address.Street;
}

myDataContext.Orders.Where(y =>(customer.Address == null || (string.IsNullOrEmpty(custStreet) || y.Customers.Addresses.Street == custStreet)))

运行良好。我不已了解其中的原因。我也不想执行拉姆达语句本身之前定义的变量无数

it runs fine. I don't undestand the reason for that. I also don't want to define countless variables before executing the Lambda statement itself.

也请注意,上面LAMBDA语句是一个更大的拉姆达的一部分包含了几个这样的声明凡条款。我知道我可以用表达​​式树工作,但已经远编码这个,我真的不希望立即切换。

Please also note that above Lambda statement is part of a much bigger Lambda Where clause that contains a few more of such statements. I know I could work with Expression Trees but having coded this far, I really don't want to switch now.

修改

作为问题得到回答,我会告诉你我是如何工作的周围:我自己建一个递归的属性初始化。这不是一个字符串列表/数组或一个原始类型一切都抛出对激活类。我从的想法在这里并做了一些修改它(基本上忽略不需要初始化一切和而不是 Activator.CreateInstance(Type.GetType(property.PropertyType.Name)); 我用 Activator.CreateInstance(property.PropertyType)); 我甚至不知道,如果在原来的问题使用的版本会工作或者为什么有人想使用它。)

as the question was answered, I'm going to tell you how I worked around it: I build myself a recursive property initializer. Everything that is not a string, a list/array or a primitive type is thrown against the Activator class. I got the idea from here and made a few changes to it (basically, ignore everything that doesn't need to be initialized and instead of Activator.CreateInstance(Type.GetType(property.PropertyType.Name)); I used Activator.CreateInstance(property.PropertyType)); I'm not even sure if the version used in the original question would work or why anyone would want to use it.)

表达式的值 customer.Address.Street 必须的评估它的价值*前的查询可以翻译成SQL。该表达不能在底层SQL留待数据库可能或可能不,计算为一个值。查询供应商必须以确定SQL应该是什么样子无条件地评价它。所以,是的,你需要进行表达的空检查的之外的。当然也有任意数量的,你可以这样做的方式,但空检查逻辑的确实的需要是查询提供翻译的表达之外。

The value of the expression customer.Address.Street must be evaluated to its value *before the query can be translated into SQL. That expression cannot be left in the underlying SQL for the database to possibly, or possibly not, evaluate to a value. The query provider has to evaluate it unconditionally in order to determine what the SQL should look like. So yes, you do need to perform the null check outside of the expression. There are of course any number of ways you could do so, but that null checking logic does need to be outside of the expression the query provider translates.