动态LINQ表达式中的空引用异常

时间:2009-09-18 14:18:51

标签: c# linq dynamic-linq

我正在使用Microsoft的Dynamic Linq Library / Sample对列表进行排序。例如,我有以下C#代码:

   myGrid.DataSource=repository.GetWidgetList()
         .OrderBy(sortField + " " + sortDirection).ToList();

我有一个案例,我的Object与另一个对象有0:1的关系,该对象具有可能在网格中显示的属性。当我们尝试对它进行排序时,只要我的所有小部件都有这个孩子,它就能正常工作。我们按Child.Name排序。但是当Child为null时,我们得到空引用异常。

我在这里有一些选项,我知道我可以选择一个匿名类型并绑定到那个,我也可以在父对象上公开Child.Name并通过代码处理它(我不喜欢包含我的对象)这个模型)。

在理想的世界里,我想更新库以处理这种情况。在我深入研究它之前,我想知道是否有人遇到过这个问题并且已经有了解决方案吗?

修改

看起来我的解释不够好。我使用Dynamic Linq Library附带的C# samples。这个库添加了一些很好的扩展,让你在lambda表达式中使用一个字符串所以我的代码实际上是这样的:

private  void BindGrid(sortField,sortDirection)
{

     this.grid.DataSource=....OrderBy("MyField ASC")....
}

当然,字符串被参数替换。但这允许我们在用户点击网格标题时动态更改排序。我们没有必要的其他逻辑来处理所有的排列。

我的解决方案正如我所描述的那样,将我干净的方法改为:

private void BindGrid()
{
   var sortField=this._sortField;
   if (sortField=="Child.Name")
   {
       sortField="iif(Child==null,null,Child.Name)";
   }
   this.grid.DataSource=repository.GetWidgetList()
                                  .OrderBy(sortField + " " + this._sortDirection)
                                  .ToList();
}

虽然这有效,但现在这意味着我必须更新此代码,因为我们要添加我们想要在子网对象上的网格中公开的新字段或属性。

4 个答案:

答案 0 :(得分:5)

如果我理解正确,我想你想要这个:

repository.GetParentObjects()
    .OrderBy(p => p.Child == null ? "" : p.Child.Name);

LINQ将能够生成模仿此表达式的SQL。

答案 1 :(得分:2)

在解决方案上我发现在我的情况下哪个不理想再次检测表达式何时访问子进程,将排序表达式更改为

iif(Child == null,null,Child.Name) ASC

理想情况下,这个逻辑可以融入到动态库中,我宁愿不必在整个地方修改每个网格来处理这会影响的所有情况。

答案 2 :(得分:1)

我遇到了同样的问题,但我找到的最佳解决方案是将代码更改为通用代码:

private void BindGrid()
{
    var sortField = this._sortField;
    var splitted_sortField = this._sortField.Split(new char[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
    if (splitted_sortField.Length > 1)
    {
        sortField = "iif("+splitted_sortField[0]+"==null,null,"+sortField+")";
    }
    this.grid.DataSource = repository.GetWidgetList()
                                     .OrderBy(sortField + " " + this._sortDirection)
                                     .ToList();
}

不完美,不会让孩子接触孩子,但每次你找到一个新的可以入罪的孩子时,都不会更新你的代码。

答案 3 :(得分:-2)

我真的不明白这个问题(可能是因为已经是星期五晚上了......),但是你不能像这样排序这个列表:

   myGrid.DataSource=repository.GetWidgetList()
     .OrderBy(w => w.SortField).ToList();

其中SortField是您要排序的属性。 即使值为null,这也应该有效......

很抱歉,如果它可能完全不合适......