C# 动态LINQ表达式中的Null引用异常

C# 动态LINQ表达式中的Null引用异常,c#,linq,dynamic-linq,C#,Linq,Dynamic Linq,我正在使用微软的动态Linq库/示例对列表进行排序。例如,我有以下C代码: myGrid.DataSource=repository.GetWidgetList() .OrderBy(sortField + " " + sortDirection).ToList(); 我的对象与另一个对象的关系为0:1,该对象的属性可能显示在网格中。当我们尝试对其进行排序时,只要我的所有小部件都有这个子部件,它就可以正常工作。我们是按孩子订购的。例如名字。然而,当Child为null时

我正在使用微软的动态Linq库/示例对列表进行排序。例如,我有以下C代码:

   myGrid.DataSource=repository.GetWidgetList()
         .OrderBy(sortField + " " + sortDirection).ToList();
我的对象与另一个对象的关系为0:1,该对象的属性可能显示在网格中。当我们尝试对其进行排序时,只要我的所有小部件都有这个子部件,它就可以正常工作。我们是按孩子订购的。例如名字。然而,当Child为null时,我们会得到null引用异常

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

在理想情况下,我希望更新库以处理此情况。在我深入研究之前,我想知道是否有人遇到过这个问题,并且已经有了解决方案

编辑

看来我解释得不够好。我正在使用随附的。该库添加了一些不错的扩展,让您可以使用字符串代替lambda表达式,因此我的代码实际上是这样的:

private  void BindGrid(sortField,sortDirection)
{

     this.grid.DataSource=....OrderBy("MyField ASC")....
}
   myGrid.DataSource=repository.GetWidgetList()
     .OrderBy(w => w.SortField).ToList();
当然,那里的字符串将替换为参数。但这允许我们在用户单击网格头时动态更改排序。我们不必使用if-then-else逻辑来处理所有排列

我的解决方案将我的nice clean方法更改为:

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();
}

虽然这样做有效,但这意味着我必须在添加新字段或属性时更新代码,这些字段或属性要在子对象的网格中公开。

在解决方案中,我发现在我的情况下,不理想的方法是检测表达式何时访问子对象,将排序表达式更改为

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

理想情况下,这种逻辑可以被烘焙到动态库中,我不想修改每个网格来处理所有可能会影响的情况。

我不太理解这个问题,可能是因为现在已经是周五晚上了…,但你不能像这样对列表排序:

private  void BindGrid(sortField,sortDirection)
{

     this.grid.DataSource=....OrderBy("MyField ASC")....
}
   myGrid.DataSource=repository.GetWidgetList()
     .OrderBy(w => w.SortField).ToList();
其中,SortField是要排序的属性。 即使该值为空,也应能正常工作


很抱歉,这可能完全离题了…

如果我理解正确,我想您需要:

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

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

我也有同样的问题,但我找到的最佳解决方案是将代码更改为以下形式,使其更通用:

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();
}

不完美,不想让您访问childs of childs,但可以避免您在每次获得新的可为空的子项时更新代码。

不,这不是我所指的。动态linq是C示例代码的一部分,例如,它允许您使用字符串作为OrderBy。它在运行时将字符串编译为lambda表达式。为什么此答案被接受为实际答案?我的处境也一样,你完全没有抓住重点。既然你不是唯一的一个,我一定没有解释清楚。我更新了这个问题,使它可能稍微清晰一些。