Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在linq查询中处理可为null的bool_C#_Linq - Fatal编程技术网

C# 在linq查询中处理可为null的bool

C# 在linq查询中处理可为null的bool,c#,linq,C#,Linq,我有一种情况,我将null bool传递给方法,然后在linq查询中,如果该参数为null,那么我需要获取所有记录,否则进行比较并返回相对值 以下是我尝试过的(将方法简化为只问相关问题) 公共列表获取(bool?allocated=null){ 返回(从DbContext.Something中的x返回) 其中x.Active&(allocated==null | | x.allocated==allocated.Value) 选择x).ToList(); } 我还检查了是否分配了HasValu

我有一种情况,我将null bool传递给方法,然后在linq查询中,如果该参数为null,那么我需要获取所有记录,否则进行比较并返回相对值

以下是我尝试过的(将方法简化为只问相关问题)

公共列表获取(bool?allocated=null){
返回(从DbContext.Something中的x返回)
其中x.Active&(allocated==null | | x.allocated==allocated.Value)
选择x).ToList();
}
我还检查了是否分配了
HasValue
,但每次都会出现相同的问题

我得到的例外是:

System.InvalidOperationException:“可为null的对象必须有一个值。”


我现在还不清楚为什么会失败,但是当我遇到这样的问题时,我倾向于简化查询。特别是,“表达式树到SQL”转换代码所做的工作越少,就越有可能工作

假设
allocated==null
不会在查询过程中更改,我会尝试将代码更改为仅有条件地查询该部分

public List<Something> Fetch(bool? allocated = null)
{
     var query = DbContext.Something.Where(x => x.Active);
     if (allocated != null)
     {
         // Do this outside the lambda expression, so it's just bool in the expression tree
         bool allocatedValue = allocated.Value;
         query = query.Where(x => x.Allocated == allocatedValue);
     }
     return query.ToList();
}
公共列表获取(bool?allocated=null)
{
var query=DbContext.Something.Where(x=>x.Active);
如果(已分配!=null)
{
//在lambda表达式之外执行此操作,因此它只是表达式树中的布尔
bool allocatedValue=已分配的.Value;
query=query.Where(x=>x.Allocated==allocatedValue);
}
返回query.ToList();
}

投票支持Jon Skeet的回答

但有一些解释说明了为什么会发生这种情况, Linq处理空值没有问题

但是LINQtoSQL或LINQtoEntities(EF)投影的行为会有所不同!不确定是bug还是特性,但无法转换为t-SQL。 谷歌搜索:LINQtoEntities或LINQtoSQL比较可空类型以获得答案

为了避免无法转换为T-SQL的NULL=1比较,我通常这样做

var allocated = (bool?)null;
 public List<Something> Fetch(bool? allocated = null){
     if(allocated != null)
     {
         allocated = allocated.Value;
     }
   return (from x in DbContext.Something 
            where x.Active && (allocated == null || x.Allocated == allocated)
            select x).ToList();
}
这对默认为“null”的方法可选参数不起作用

证明以下观点的小型试验:

private void MyTest()
{
    var result = FetchListLinq(true);
    result = FetchDbContextLinq(true);
    result = FetchListLinq();
    result = FetchDbContextLinq();
}

private List<object> FetchListLinq(bool? allocated = null)
{
    var myList = new List<dynamic>() { new { Id = 1, Allocated = true, Active = true }, new { Id = 2, Allocated = false, Active = true }, new { Id = 3, Allocated = true, Active = false } };
   return (from x in myList
                   where x.Active && (allocated == null || x.Allocated == allocated.Value)
                   select x).ToList();
}

private List<object> FetchDbContextLinq(bool? allocated = null)
{
    // allocated = allocated ?? (bool?)null; // fix for Linq to SQL or Linq to Entity
    var notWorking = (from x in DbContext.Something
                      where x.Active && (allocated == null || x.Allocated == allocated.Value)
                      select x).ToList();
}
private void MyTest()
{
var result=FetchListLinq(true);
结果=FetchDbContextLinq(真);
结果=FetchListLinq();
结果=FetchDbContextLinq();
}
私有列表FetchListLinq(bool?allocated=null)
{
var myList=new List(){new{Id=1,Allocated=true,Active=true},new{Id=2,Allocated=false,Active=true},new{Id=3,Allocated=true,Active=false};
返回(从myList中的x开始)
其中x.Active&(allocated==null | | x.allocated==allocated.Value)
选择x).ToList();
}
私有列表FetchDbContextLinq(bool?allocated=null)
{
//已分配=已分配???(bool?)null;//修复Linq到SQL或Linq到实体
var notWorking=(来自DbContext.Something中的x
其中x.Active&(allocated==null | | x.allocated==allocated.Value)
选择x).ToList();
}

不要像约翰·斯基特(John skeet)中提到的那样单独使用where子句,而是简单地这样做

var allocated = (bool?)null;
 public List<Something> Fetch(bool? allocated = null){
     if(allocated != null)
     {
         allocated = allocated.Value;
     }
   return (from x in DbContext.Something 
            where x.Active && (allocated == null || x.Allocated == allocated)
            select x).ToList();
}
公共列表获取(bool?allocated=null){
如果(已分配!=null)
{
已分配=已分配。值;
}
返回(从DbContext.Something中的x返回)
其中x.Active&(allocated==null | | x.allocated==allocated)
选择x).ToList();
}

我查过了。它工作正常

我假设这是一个异常而不是编译时错误?请提供更多详细信息,最好是堆栈跟踪,当然还有异常类型。知道
x.Allocated
的类型也很好。是的,它是例外。将更新问题。而x.Allocated也是boolI希望在同一where子句中有一个解决方案。但由于这一点对其他人的参考是有效的,所以我将把它标记为答案。也许最好使用
if(allocated.HasValue)
@asd:这完全等同于
if(allocated!=null)
@Ahmad:虽然这样做可能是可行的,但我怀疑让它工作并让它继续工作比它的价值更大。如果这也生成了更可读的SQL,我也不会感到惊讶。