从一组对象动态构建lambda表达式?

Sve*_*ang 8 c# linq lambda linq-to-objects kendo-ui-mvc

我有一个以这种格式存储的排序列表:

public class ReportSort
{
    public ListSortDirection SortDirection { get; set; }
    public string Member { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我需要把它变成类型的lambda表达式 Action<DataSourceSortDescriptorFactory<TModel>>

假设我有以下报告排序集合:

new ReportSort(ListSortDirection.Ascending, "LastName"),
new ReportSort(ListSortDirection.Ascending, "FirstName"),
Run Code Online (Sandbox Code Playgroud)

我需要将它转换为这样的语句,如下所示:

.Sort(sort => { 
        sort.Add("LastName").Ascending();
        sort.Add("FirstName").Ascending();
      })
Run Code Online (Sandbox Code Playgroud)

排序方法签名是:

public virtual TDataSourceBuilder Sort(Action<DataSourceSortDescriptorFactory<TModel>> configurator)
Run Code Online (Sandbox Code Playgroud)

所以我现在有一些方法:

public static Action<DataSourceSortDescriptorFactory<TModel>> ToGridSortsFromReportSorts<TModel>(List<ReportSort> sorts) where TModel : class
    {
        Action<DataSourceSortDescriptorFactory<TModel>> expression;
        //stuff I don't know how to do
        return expression;
    }
Run Code Online (Sandbox Code Playgroud)

......我不知道该怎么办

编辑:答案是:

var expression = new Action<DataSourceSortDescriptorFactory<TModel>>(x =>
        {
            foreach (var sort in sorts)
            {
                if (sort.SortDirection == System.ComponentModel.ListSortDirection.Ascending)
                {
                    x.Add(sort.Member).Ascending();
                }
                else
                {
                    x.Add(sort.Member).Descending();
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

我一开始想我必须使用Expression类从头开始动态构建lambda表达式.幸运的是,事实并非如此.

Eri*_*ert 5

......我不知道该怎么办

好吧,推理出来.

你手头有什么?一个List<ReportSort>sorts.

你需要什么?安Action<Whatever>.

你已经迈出了第一步:你已经制定了一个方法来接受你拥有的东西并返回你需要的东西.伟大的第一步.

    Action<DataSourceSortDescriptorFactory<TModel>> expression;
    //stuff I don't know how to do
    return expression;
Run Code Online (Sandbox Code Playgroud)

而你已经喊出了你不知道该怎么做的事情.这是一个很好的技术.

首先填写编译但无法正常工作的内容.

Action<DataSourceSortDescriptorFactory<TModel>> expression = 
  sort => {         
    sort.Add("LastName").Ascending();
    sort.Add("FirstName").Ascending();
  };
return expression;
Run Code Online (Sandbox Code Playgroud)

优秀. 现在你有了一个编译程序,这意味着你可以运行你的测试并验证如果这种情况是预期的,那么测试就会通过,如果还需要其他任何东西,那么测试就会失败.

现在想想,我手头有什么?我有一份清单,我正在做的Action.这意味着副作用正在发生,可能涉及列表中的每个项目.所以那里可能有一个foreach地方:

Action<DataSourceSortDescriptorFactory<TModel>> expression = 
  sort => {         
    sort.Add("LastName").Ascending();
    sort.Add("FirstName").Ascending();
    foreach(var sort in sorts) { 
      // Do something
    }
  };
return expression;
Run Code Online (Sandbox Code Playgroud)

编译它.它失败.啊,我们已经混淆了我们添加的新排序.解决问题.

Action<DataSourceSortDescriptorFactory<TModel>> expression = 
  existingSort => {         
    existingSort.Add("LastName").Ascending();
    existingSort.Add("FirstName").Ascending();
    foreach(var newSort in sorts) { 
      // Do something
    }
  };
return expression;
Run Code Online (Sandbox Code Playgroud)

太好了,现在我们再次能够编译和运行测试.

这里的模式应该清楚. 继续编译,继续运行测试,逐步使您的程序越来越正确,理解您可以对您手头的值执行的操作.

你能完成它吗?