MVC4将lambda从控制器传递到存储库

时间:2014-01-27 17:46:29

标签: c# linq asp.net-mvc-4

我有一个控制器,它调用我的存储库中的一个方法,该方法运行linq to entities查询以获取我的应用程序的产品列表。我想为用户添加过滤结果的能力(例如标准价格从高到低,从低到高等等)。

所以我想我需要在存储库中动态填充我的orderby,但是我遇到了麻烦。我对c#中的泛型不满意,所以请耐心等待。

控制器

model.Products = ProdRepo.GetProducts ((int)CategoryId, 0, 8);

模型

    //get a list of the products
    public List<ProductModel> GetProducts (int CategoryId, int Start, int End) 
    {
        List<ProductModel> Products = new List<ProductModel>();
        var products = (from p in db.products select p).AsEnumerable().OrderByWithDirection(x=> x.date_added, true).Where( x => x.category_id == CategoryId).Where((row, index) => index >= Start && index < End).ToList();
            if (products.Count > 0)
            {
                foreach (var item in products)
                {
                    ProductModel model = new ProductModel();
                    model.CategoryId = item.category_id;
                    model.Description = item.description;
                    model.Id = item.id;
                    model.Product = item.product1;
                    model.DateAdded = item.date_added;
                    model.Image = item.image;
                    model.Price = item.price;

                    Products.Add(model);
                }
            }
      }

所以我认为我需要从我的控制器传递一个Func<TSource, TKey>,但我无法拼凑如何完成它。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

您可以通过传递Func<IQueryable<T>, IOrderedQueryable<T>>来完成此操作,在这种情况下将是

 public List<ProductModel> GetProducts (int CategoryId, int Start, int End, Func<IQueryable<ProductModel>, IOrderedQueryable<ProductModel>> order? = null)
 {
  //code shown in question

  if( order != null )
  {
   Products = order(Products).ToList();
  }
 }

你可以这样称呼它:

model.Products = ProdRepo.GetProducts ((int)CategoryId, 0, 8, order: q => q.OrderBy(prod => prod.SomeField));

答案 1 :(得分:1)

我假设斗争正在进行,因为排序元素并不总是相同的类型。通过传递泛化泛型,不是过分复杂一个相当简单的选择,为什么不在传递选项并在构建linq查询时考虑它呢?

在我工作场所的代码中,我们可能会通过枚举实现这一点,例如:

public enum OrderByValue
{
    DateAdded,
    Price,
    OtherChoice
}

然后,您的查询将决定在中间做出:

var products = (from p in db.products select p).AsEnumerable();
switch(orderByValue)
{
    case OrderByValue.DateAdded:
    products = products.OrderByWithDirection(x=> x.date_added, true);
    break;

    case OtherStuff:
    ...
}
products = products.Where( x => x.category_id == CategoryId)
    .Where((row, index) => index >= Start && index < End)
    .ToList();

如果它实际上只是一个二元选择,你也可以在没有枚举和开关的情况下做同样的事情,只需传入一个bool。