Null Reference Exception in a Dynamic LINQ Expression

Asked
Viewd4978

6

I am using the Dynamic Linq Library / Sample from Microsoft to do ordering on a list. So for example I have the following C# code:

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

I have a case where my Object have a 0:1 relationship with another object, which has a property that might be displayed in the grid. When we try and sort this, it works fine so long as all my Widgets have this child. We are ordering by Child.Name for example. When Child is null however, we get the null reference exception.

I have some options here which I know I could select into an anonymous type and bind to that, I could also expose the Child.Name on the parent object and handle this via code (Which I don't like comprising my object model for this).

In an ideal world I'd like to update the library to handle this case. Before I dive into it, I'm wondering if anyone has ran across this or not and has a solution already?

Edit

Looks like I didn't explain well enough. I am using the Dynamic Linq Library which comes with the C# samples. This library adds some nice extensions that let you use a string inplace of a lambda expression So my code is actually something like this:

private  void BindGrid(sortField,sortDirection)
{

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

Of course the string there is replaced with the parameters. But this allows us to change the sorting dynamically as the user clicks on a grid header. We don't have to if then else logic to handle all the permutations.

My solution as I documented bellow changes my nice clean method into:

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

And while this works, this now means I have to update this code as we add new fields or properties which we want to expose in the grid which are on a child object.

4 个答案

5

如果我对您的理解正确,我想你会这样:

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

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

  • Nope this is not what I am referring to. The dynamic linq is part of the C# sample code and lets you use a string as an OrderBy for example. It compiles the string to a lambda expression at run time.

    JoshBerkeSeptember 18, 2009 16:37
-2

我不太了解这个问题(也许是因为已经是星期五晚上了……),但是您不能像这样对列表进行排序:

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

其中SortField是要排序的属性。 即使该值为null,它也应该起作用。

对不起,如果它完全不重要了……

  • You completly missed the point. Since your not the only I must have not explained myself well enough. I updated the question so it is probally a little but more clear.

    JoshBerkeSeptember 18, 2009 16:46
2

在解决方案上,我发现在我看来还是不理想的解决方案是检测表达式何时将访问子级,将排序表达式更改为

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

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

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

并不完美,不希望允许访问childs子级,但是可以避免u每次获得新的可为空的子级时更新代码。