我正在尝试创建访问数据库的通用方法。这将暗示参数,例如:页面索引,每页显示的项目数,订购选项,加载选项等。

...

public IQuerable<T> GetAll(int pageIndex, int itemsToDisplayPerPage, System.Linq.Expressions.Expression<Func<T,object>>[] orderBy, System.Linq.Expressions.Expression<Func<T,object>>[] loadOptions)
{
  DataContext dc = null;
  IQuerable<T> result = null;
  // Make some initalizations
  ...
  foreach(var item in orderBy)
  {
    result = result.OrderBy(item);
  }

  System.Data.Linq.DataLoadOptions loadOptions = new System.Data.Linq.DataLoadOptions();
  foreach(var item in loadOptions)
  {
    loadOptions.LoadWith(item);
  }
  ...
}

...


问题是System.Linq.Expressions.Expression< Func< T,object > >类型不能很好地代表将要为上述两个示例传递的任何lambda表达式。

由于对象类型对于订购没有意义,因此在订购时会崩溃。同样在loadWith上将不起作用。所以我不知道我该怎么处理这个问题。有什么建议么?谢谢。

最佳答案

由于我们对实体使用linq,因此不确定LoadWith,但是我们成功地使orderby可以在存储库Get方法中使用。客户端代码如下所示:

var results = _repository.GetAll(
    new GetAllCriteria()
        .OrderBy(x => x.Property1)
        .OrderBy(x => x.Property2)
);


我们还没有在存储库方法中使用泛型,这可能会在将来的重构中出现。但是条件实现看起来像这样:

public class GetAllCriteria
{
    public Dictionary<Expression<Func<CustomType, object>>, bool> ToBeOrderedBy
    {
        get; private set;
    }

    public GetAllCriteria OrderBy(
        Expression<Func<CustomType, object>> expression)
    {
        return OrderBy(expression, true);
    }

    public GetAllCriteria OrderByDescending(
        Expression<Func<CustomType, object>> expression)
    {
        return OrderBy(expression, false);
    }

    private GetAllCriteria OrderBy(
        Expression<Func<CustomType, object>> expression, bool isAscending)
    {
        if (expression != null)
        {
            if (ToBeOrderedBy == null)
                ToBeOrderedBy = new Dictionary<Expression<Func<CustomType, object>>, bool>();
            ToBeOrderedBy.Add(expression, isAscending);
        }
        return this;
    }
}


然后,存储库命令如下:

public Collection<CustomType> GetAll(GetAllCriteria criteria)
{
    var query = dbContext.CustomTypes.AsQueryable();

    // some code

    // apply order by
    if (criteria.ToBeOrderedBy != null && criteria.ToBeOrderedBy.Count > 0)
    {
        var firstOrderBy = criteria.ToBeOrderedBy.First();
        query = firstOrderBy.Value
            ? query.OrderBy(firstOrderBy.Key)
            : query.OrderByDescending(firstOrderBy.Key);

        query = criteria.ToBeOrderedBy.Skip(1).Aggregate(query,
            (lastOrderBy, nextOrderBy) => nextOrderBy.Value
            ? ((IOrderedQueryable<CustomType>)lastOrderBy)
                .ThenBy(nextOrderBy.Key)
            : ((IOrderedQueryable<CustomType>)lastOrderBy)
                .ThenByDescending(nextOrderBy.Key));
    }

    // some more code

    var results = query.ToList();
    return results;
}


如果这与linq到实体一起工作,我想它应该与linq到sql一起工作。

关于c# - 如何保留对稍后将传递给OrderBy或LoadWith函数的lambda表达式的引用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8438625/

10-12 17:27