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

发布于 2024-08-04 23:08:40 字数 1525 浏览 4 评论 0原文

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

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

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

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

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

编辑

看来我解释得不够好。我正在使用 动态 Linq 库,随 C# 一起提供样本。这个库添加了一些很好的扩展,让您可以使用字符串代替 lambda 表达式所以我的代码实际上是这样的:

private  void BindGrid(sortField,sortDirection)
{

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

当然,那里的字符串被参数替换。但这允许我们在用户单击网格标题时动态更改排序。我们不必使用 if then else 逻辑来处理所有排列。

我在下面记录的解决方案将我的干净方法更改为:

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

似最初 2024-08-11 23:08:40

如果我理解正确的话,我认为您想要这样:

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

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

If I understand you correctly, I think you want this:

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

LINQ will be able to generate SQL that mimics this expression.

演多会厌 2024-08-11 23:08:40

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

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

理想情况下,可以将此逻辑烘焙到动态库中,我宁愿不必修改各处的每个网格来处理这将影响的所有情况。

On solution I've found which in my case is not ideal again would be to detect when the expression is going to access the child, to change the sort expression to be

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

Ideally this logic can be baked into the dynamic library, I'd rather not have to modify each grid all over the place to handle all the cases this will impact.

本宫微胖 2024-08-11 23:08:40

我遇到了同样的问题,但我发现的最好的解决方案是将您的代码更改为这样,使您的代码更加通用:

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

不完美,不喜欢授予孩子的孩子访问权限,但可以让您免于每次更新代码获得一个新的可为 null 的孩子。

I had the same issue but the best solution I found was to make your code a little more generic by changing it into this:

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

Not perfect, won't like give access to childs of childs, but saves u from updating your code every time u get a new nullable child.

扛起拖把扫天下 2024-08-11 23:08:40

我不太明白这个问题(也许因为这里已经是周五晚上了......),但是你不能像这样对列表进行排序吗:

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

其中 SortField 是你想要排序的属性。
即使该值为空,这也应该起作用...

抱歉,如果它可能完全离题...

I don't really understand the problem (maybe because it is friday evening here already...), but can't you sort the list like this:

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

where SortField is the property you want to sort on.
This should work even when the value is null...

Sorry if it's maybe completely beside the point...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文