如何动态执行多个Linq to Entities排序

akn*_*ds1 4 .net c# linq linq-to-entities sql-order-by

所以我的问题是这样的; 在C#代码中,我需要在Linq to Entities的帮助下执行实体集的多个排序,具体取决于输入参数.有三列要订购,订货列的顺序本身是可变的(这意味着对于每个订单,我需要查找要订购的列).我怎样才能做到这一点?

我有一些代码应该可以工作,但我重复自己太多了,因为我无法参数化我的操作(Linq to Entities是非常严格的wrt.我允许在我的lambdas中做什么).请建议我如何根据DRY原则重写我的代码,也许是在T4代码生成的帮助下?

以下代码应说明我的问题.这是真实代码的摘录,为简洁起见,请告诉我是否应该包含更多内容.该orderSpecs变量是"订单规范"的数组,每个订单规范指定要订购的列以及是否以降序排序.该orderSpecs阵列至少有一个元素,因此至少执行一次排序.

using (var db = new MyContainer())
{
    var orderSpec = orderSpecs[0];
    IQueryable<DbVersion> dVersions = null;
    if (orderSpec.Column == 0)
    {
        if (orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(ver => ver.Name);
        }
        else
        {
            dVersions = db.Versions.OrderBy(ver => ver.Name);
        }
    }
    else if (orderSpec.Column == 1)
    {
        if (orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(ver => ver.Built);
        }
        else
        {
            dVersions = db.Versions.OrderBy(ver => ver.Built);
        }
    }
    else if (orderSpec.Column == 2)
    {
        if (orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(ver => ver.Id);
        }
        else
        {
            dVersions = db.Versions.OrderBy(ver => ver.Id);
        }
    }

    foreach (var spec in orderSpecs.Skip(1))
    {
        if (spec.Column == 0)
        {
            if (spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(ver => ver.Name);
            }
            else
            {
                dVersions = dVersions.ThenBy(ver => ver.Name);
            }
        }
        else if (spec.Column == 1)
        {
            if (spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(ver => ver.Built);
            }
            else
            {
                dVersions = dVersions.ThenBy(ver => ver.Built);
            }
        }
        else if (spec.Column == 2)
        {
            if (spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(ver => ver.Id);
            }
            else
            {
                dVersions = dVersions.ThenBy(ver => ver.Id);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Phi*_*ier 14

如何创建一个字典来映射这些colums,这些colums导致这些巨大的if-else结构到属性.看起来像这样:

using (var db = new MyContainer())
{
    var orderSpec = orderSpecs[0];
    IQueryable<DbVersion> dVersions = null;

    var mapping = new Dictionary<int, Func<DbVersion, object>>()
    {
        { 0, ver => ver.Name },
        { 1, ver => ver.Built },
        { 2, ver => ver.Id }
    };

    if (orderSpec.Descending)
        dVersions = db.Versions.OrderByDescending(mapping[orderSpec.Column]);
    else
        dVersions = db.Versions.OrderBy(mapping[orderSpec.Column]);

    foreach (var spec in orderSpecs.Skip(1))
    {
        if (spec.Descending)
            dVersions = dVersions.ThenByDescending(mapping[spec.Column]);
        else
            dVersions = dVersions.ThenBy(mapping[spec.Column]);
    }
}
Run Code Online (Sandbox Code Playgroud)