EntityFramework:我们可以最小化排序代码

时间:2018-02-06 12:51:26

标签: entity-framework

我使用EF从db获取数据。当我提取然后我也过滤和排序数据。这样我按列名排序。我必须写出看起来不太好的大行。

    switch (SortColumn)
    {
        case "CompanyName":
            ViewBag.OldSort = "CompanyName";
            if (SortColumn.Equals(CurrentSort))
            {
                customer = customer.OrderByDescending(m => m.CompanyName);
                ViewBag.CurrentSort = "";
                ViewBag.SortOrder = "desc";
            }
            else
            {
                customer = customer.OrderBy(m => m.CompanyName);
                ViewBag.SortOrder = "asc";
            }
            break;

        case "ContactName":
            ViewBag.OldSort = "ContactName";
            if (SortColumn.Equals(CurrentSort))
            {
                customer = customer.OrderByDescending(m => m.ContactName);
                ViewBag.CurrentSort = "";
                ViewBag.SortOrder = "desc";
            }
            else
            {
                customer = customer.OrderBy(m => m.ContactName);
                ViewBag.SortOrder = "asc";
            }
            break;

        case "ContactTitle":
            ViewBag.OldSort = "ContactTitle";
            if (SortColumn.Equals(CurrentSort))
            {
                customer = customer.OrderByDescending(m => m.ContactTitle);
                ViewBag.CurrentSort = "";
                ViewBag.SortOrder = "desc";
            }
            else
            {
                customer = customer.OrderBy(m => m.ContactTitle);
                ViewBag.SortOrder = "asc";
            }
            break;

        case "Address":
            ViewBag.OldSort = "Address";
            if (SortColumn.Equals(CurrentSort))
            {
                customer = customer.OrderByDescending(m => m.Address);
                ViewBag.CurrentSort = "";
                ViewBag.SortOrder = "desc";
            }
            else
            {
                customer = customer.OrderBy(m => m.Address);
                ViewBag.SortOrder = "asc";
            }
            break;

        case "Default":
            ViewBag.OldSort = "CompanyName";
            customer = customer.OrderBy(m => m.CompanyName);
            ViewBag.SortOrder = "asc";
            break;
    }

请参阅4列我必须编写这么多行代码。假设我需要使用40列,那么我需要写多少行。所以告诉我在使用EF时最小化排序代码的最佳选择。

修改

查看我的完整工作代码,其中给出了完整的代码,以了解我使用过滤器对数据进行排序和获取的方法。现在告诉我如何最小化排序代码,使用提取数据进行过滤。

private CustomersEntities db = new CustomersEntities();
        public int recordcount = 0;

        // GET: Customers
        public ActionResult Index(int? page, string SortColumn, string CurrentSort, String SearchText)
        {
            var customer = (from s in db.Customers
                            // select s;
                            select new CustomerDTO
                            {
                                CustomerID = s.CustomerID,
                                CompanyName = s.CompanyName,
                                ContactName = s.ContactName,
                                ContactTitle = s.ContactTitle,
                                Address = s.Address
                            });

            int pageSize = 5;
            int pageNumber = (page ?? 1);
            ViewBag.CurrentPage = pageNumber;
            SortColumn = String.IsNullOrEmpty(SortColumn) ? "CompanyName" : SortColumn;
            ViewBag.CurrentSort = SortColumn;
            //ViewBag.OldSort = CurrentSort;
            ViewBag.SearchText = SearchText;

            if (!String.IsNullOrEmpty(SearchText))
            {
                customer = customer.Where(s => s.CompanyName.ToUpper().Contains(SearchText.ToUpper())
                || s.ContactName.ToUpper().Contains(SearchText.ToUpper())
                || s.ContactTitle.ToUpper().Contains(SearchText.ToUpper())
                || s.Address.ToUpper().Contains(SearchText.ToUpper()));
            }

            switch (SortColumn)
            {
                case "CompanyName":
                    ViewBag.OldSort = "CompanyName";
                    if (SortColumn.Equals(CurrentSort))
                    {
                        customer = customer.OrderByDescending(m => m.CompanyName);
                        ViewBag.CurrentSort = "";
                        ViewBag.SortOrder = "desc";
                    }
                    else
                    {
                        customer = customer.OrderBy(m => m.CompanyName);
                        ViewBag.SortOrder = "asc";
                    }
                    break;

                case "ContactName":
                    ViewBag.OldSort = "ContactName";
                    if (SortColumn.Equals(CurrentSort))
                    {
                        customer = customer.OrderByDescending(m => m.ContactName);
                        ViewBag.CurrentSort = "";
                        ViewBag.SortOrder = "desc";
                    }
                    else
                    {
                        customer = customer.OrderBy(m => m.ContactName);
                        ViewBag.SortOrder = "asc";
                    }
                    break;

                case "ContactTitle":
                    ViewBag.OldSort = "ContactTitle";
                    if (SortColumn.Equals(CurrentSort))
                    {
                        customer = customer.OrderByDescending(m => m.ContactTitle);
                        ViewBag.CurrentSort = "";
                        ViewBag.SortOrder = "desc";
                    }
                    else
                    {
                        customer = customer.OrderBy(m => m.ContactTitle);
                        ViewBag.SortOrder = "asc";
                    }
                    break;

                case "Address":
                    ViewBag.OldSort = "Address";
                    if (SortColumn.Equals(CurrentSort))
                    {
                        customer = customer.OrderByDescending(m => m.Address);
                        ViewBag.CurrentSort = "";
                        ViewBag.SortOrder = "desc";
                    }
                    else
                    {
                        customer = customer.OrderBy(m => m.Address);
                        ViewBag.SortOrder = "asc";
                    }
                    break;

                case "Default":
                    ViewBag.OldSort = "CompanyName";
                    customer = customer.OrderBy(m => m.CompanyName);
                    ViewBag.SortOrder = "asc";
                    break;
            }

            IPagedList<CustomerDTO> oCustomer = customer.ToPagedList(pageNumber, pageSize);
            return View(oCustomer);
        }

2 个答案:

答案 0 :(得分:1)

ViewBag.OldSort = SortColumn;

var arg = Expression.Parameter(typeof(Customer), "x");
var exprProp = Expression.Property(arg, SortColumn);
var projection = Expression.Lambda<Func<Customer, string>>(exprProp, arg);

if (SortColumn.Equals(CurrentSort))
{
    customer = customer.OrderByDescending(projection);
    ViewBag.CurrentSort = "";
    ViewBag.SortOrder = "desc";
}
else
{
    customer = customer.OrderBy(projection);
    ViewBag.SortOrder = "asc";
}

答案 1 :(得分:0)

第一种方法

假设您的所有可排序列都是字符串:

private static readonly IReadOnlyDictionary<string, Expression<Func<Customer, string>>> SortColumns = new Dictionary<string, Expression<Func<Customer, string>>>
{
    ["CompanyName"] = c => c.CompanyName,
    ["ContactName"] = c => c.ContactName,
    ["ContactTitle"] = c => c.ContactTitle,
    ["Address"] = c => c.Address,
};

...

if (SortColumns.TryGetValue(SortColumn, out var sortProperty))
{
    ViewBag.OldSort = SortColumn;
    if (SortColumn.Equals(CurrentSort))
    {
        customer = customer.OrderByDescending(sortProperty);
        ViewBag.CurrentSort = "";
        ViewBag.SortOrder = "desc";
    }
    else
    {
        customer = customer.OrderBy(sortProperty);
        ViewBag.SortOrder = "asc";
    }
}
else
{
    customer = customer.OrderBy(c => c.CompanyName);
    ViewBag.OldSort = "CompanyName";
    ViewBag.SortOrder = "asc";
}

第二种方法

稍微复杂一些。

首先添加必要的using指令:

using System.Linq;
using System.Linq.Expressions;

接下来,您需要一种基于LambdaExpression进行排序的方法:

private static IOrderedQueryable<TSource> OrderBy<TSource>(IQueryable<TSource> source, LambdaExpression keySelector, bool descending)
{
    string methodName = descending ? "OrderByDescending" : "OrderBy";
    Type[] typeArguments = { typeof(TSource), keySelector.ReturnType };
    var query = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, keySelector);
    return (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(query);
}

然后,您需要更新字典以存储LambdaExpression值。为了干净利落,您需要一个帮助方法将匿名委托转换为LambdaExpression:

private static LambdaExpression Expr<TProperty>(Expression<Func<Customer, TProperty>> fn) => fn;

private static readonly IReadOnlyDictionary<string, LambdaExpression> SortColumns = new Dictionary<string, LambdaExpression>
{
    ["CompanyName"] = Expr(c => c.CompanyName),
    ["ContactName"] = Expr(c => c.ContactName),
    ["ContactTitle"] = Expr(c => c.ContactTitle),
    ["Address"] = Expr(c => c.Address),
};

最后,更新您的排序代码以使用新方法:

if (SortColumns.TryGetValue(SortColumn, out var keySelector))
{
    ViewBag.OldSort = SortColumn;
    if (SortColumn.Equals(CurrentSort))
    {
        customer = OrderBy(customer, keySelector, true);
        ViewBag.CurrentSort = "";
        ViewBag.SortOrder = "desc";
    }
    else
    {
        customer = OrderBy(customer, keySelector, false);
        ViewBag.SortOrder = "asc";
    }
}
else
{
    customer = customer.OrderBy(c => c.CompanyName);
    ViewBag.OldSort = "CompanyName";
    ViewBag.SortOrder = "asc";
}

现在我们可以按任何属性类型排序。