Linq表达词典

时间:2010-09-29 07:39:04

标签: c# linq-to-sql dictionary

  

可能重复:
  Declaring func<in T,Out Result> dynamically

我正在尝试使用linq-to-sql构建一个查询,为了提供排序功能,我写了这样的东西:

private Dictionary<string, Expression<Func<DataAccess.Auditing, object>>> OrderDict { get; set; }


OrderDict = new Dictionary<string,Expression<Func<Augeos.GereonWeb.DataAccess.Auditing, object>>>();
OrderDict.Add("Date", p => (DateTime)p.RequestDateTime);
OrderDict.Add("Username", p => (string)p.CdUsername);
OrderDict.Add("Portfolio", p => (string)p.CdPortfolio);
OrderDict.Add("Url", p => (string)p.RequestedUrl);
OrderDict.Add("Result", p => (bool)p.RequestResult);
OrderDict.Add("Duration", p => (float)p.RequestDuration);


private IQueryable<DataAccess.Auditing> SetOrder(string orderBy, bool orderDirection, IQueryable<DataAccess.Auditing> query)
{
    if (orderDirection)
    return query.OrderByDescending(OrderDict[orderBy]);
    else
    return query.OrderBy(OrderDict[orderBy]);
}

我的目标是使用SortOrder函数对查询进行排序。主要问题是Func返回一个对象,而linq无法对这种类型的元素进行排序。我真的需要使用object作为返回类型,因为我必须按各种类型排序。实际上是否可以稍微修改此代码并使其工作?

谢谢,

吉奥

2 个答案:

答案 0 :(得分:2)

嗯,你必须在查询的表达式树中进行非常低级别的操作才能执行此类操作。一种更简单的方法是使用DynamicLinq库,您可以使用列作为字符串值来执行.OrderBy()。可以找到文档here on Scott Guthrie's blog

答案 1 :(得分:0)

如果你想象这样订购你的查询:

query = orderDict["Date"](query, true);

然后你的字典必须这样定义:

var orderDict = new Dictionary<string, Func<IQueryable<Auditing>, bool, IQueryable<Auditing>>>();

你可以像这样添加项目:

orderDict.Add("Date", MakeOrderedQueryDelegate(a => a.RequestDateTime));
orderDict.Add("UserName", MakeOrderedQueryDelegate(a => a.CdUsername));

需要MakeOrderedQueryDelegate如下:

private Func<IQueryable<Auditing>, bool, IQueryable<Auditing>> MakeOrderedQueryDelegate<T>(Expression<Func<Auditing, T>> keyselector)
{
    return (q, descending) => { return MakeOrderedQuery(q, descending, keyselector); };
}

..你可以像这样实现MakeOrderedQuery:

private IQueryable<Auditing> MakeOrderedQuery<T>(IQueryable<Auditing> query, bool descending, 
    Expression<Func<Auditing, T>> keyselector)
{
    if (descending)
    {
        return query.OrderByDescending(keyselector);
    }
    else
    {
        return query.OrderBy(keyselector);
    }
}