如何动态地执行多个LINQ到实体排序 [英] How to perform multiple Linq to Entities orderings dynamically

查看:114
本文介绍了如何动态地执行多个LINQ到实体排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我的问题是这样的;在C#code,我需要进行设置的LINQ的帮助下实体,依赖于输入参数的实体的多个排序。有三列订购上,并且排序列的顺序是可变本身(意味着为每个订购,我需要查找命令在其上的列)。我怎样才能做到这一点?

我有一些code应该工作,但是我重复自己的方式太多了,因为我一直无法进行参数我的操作(LINQ到实体非常严格WRT的,就是我让做我的lambda表达式)。请建议我怎么可以重写我的code按照原则,也许用T code一代的帮助?

下面code应该说明我的问题。这是真正的code的摘录,为了简便起见,让我知道我是否应该包含更多。在 orderSpecs 变量是订单规格,其中每一个指定列的订购上与是否以递减方式订购的阵列。在 orderSpecs 阵列具有至少一个元素,所以至少有一个排序执行

 使用(VAR DB =新myContainer中())
{
    变种orderSpec = orderSpecs [0];
    IQueryable的< D​​bVersion> dVersions = NULL;
    如果(orderSpec.Column == 0)
    {
        如果(orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(VER => ver.Name);
        }
        其他
        {
            dVersions = db.Versions.OrderBy(VER => ver.Name);
        }
    }
    否则,如果(orderSpec.Column == 1)
    {
        如果(orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(VER => ver.Built);
        }
        其他
        {
            dVersions = db.Versions.OrderBy(VER => ver.Built);
        }
    }
    否则,如果(orderSpec.Column == 2)
    {
        如果(orderSpec.Descending)
        {
            dVersions = db.Versions.OrderByDescending(VER => ver.Id);
        }
        其他
        {
            dVersions = db.Versions.OrderBy(VER => ver.Id);
        }
    }

    的foreach(在orderSpecs.Skip VAR规范(1))
    {
        如果(spec.Column == 0)
        {
            如果(spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(VER => ver.Name);
            }
            其他
            {
                dVersions = dVersions.ThenBy(VER => ver.Name);
            }
        }
        否则,如果(spec.Column == 1)
        {
            如果(spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(VER => ver.Built);
            }
            其他
            {
                dVersions = dVersions.ThenBy(VER => ver.Built);
            }
        }
        否则,如果(spec.Column == 2)
        {
            如果(spec.Descending)
            {
                dVersions = dVersions.ThenByDescending(VER => ver.Id);
            }
            其他
            {
                dVersions = dVersions.ThenBy(VER => ver.Id);
            }
        }
    }
 

解决方案

怎么样建立一个字典映射这些colums这是造成这些巨大的if-else结构的属性。难道是这样的:

 使用(VAR DB =新myContainer中())
{
    变种orderSpec = orderSpecs [0];
    IQueryable的< D​​bVersion> dVersions = NULL;

    VAR映射=新字典< INT,Func键< D​​bVersion,对象>>()
    {
        {0,版本=> ver.Name},
        {1,版本=> ver.Built},
        {2,版本=> ver.Id}
    };

    如果(orderSpec.Descending)
        dVersions = db.Versions.OrderByDescending(映射[orderSpec.Column]);
    其他
        dVersions = db.Versions.OrderBy(映射[orderSpec.Column]);

    的foreach(在orderSpecs.Skip VAR规范(1))
    {
        如果(spec.Descending)
            dVersions = dVersions.ThenByDescending(映射[spec.Column]);
        其他
            dVersions = dVersions.ThenBy(映射[spec.Column]);
    }
}
 

So my problem is like this; in C# code, I need to perform multiple orderings of an entity set with the help of Linq to Entities, dependent on input parameters. There are three columns to order on, and the order of the ordering columns is itself variable (meaning that for each ordering, I need to look up which column to order on). How can I achieve this?

I have some code that should work, but I repeat myself way too much since I haven't been able to parameterize my operations (Linq to Entities is very restrictive wrt. what I'm allowed to do in my lambdas). Please suggest how I can rewrite my code in accordance with the DRY principle, perhaps with the help of T4 code generation?

The following code should illustrate my problem. It's an excerpt of the real code, for brevity, let me know if I should include more. The orderSpecs variable is an array of "order specifications", each of which specifying a column to order on and whether to order in a descending manner. The orderSpecs array has at least one element, so at least one ordering is performed.

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

解决方案

What about creating a dictionary for mapping these colums that are causing these huge if-else constructs to the properties. Could look like this:

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

这篇关于如何动态地执行多个LINQ到实体排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆