返回投影查询以便在之后添加过滤器的最佳方法是什么

时间:2014-05-03 04:42:32

标签: c# .net linq entity-framework

我需要进行一个查询,返回当前价格和当前减价的所有项目。

我尝试了一些解决方案,但似乎没有任何工作或尊重模式,因为我理解它们。

动态解决方案: 我试图将数据作为动态返回,其中T将是一个IQueryable(Item,CurrentItemPrice,CurrentItemStateIfAny)

    public ItemRepository(CoconutEntities context) : base(context){}   

    public dynamic GetAllCurrentItems(){
        var items = (from item in context.Items
                    select new { 
                        Item = item, 
                        CurrentItemPrice = item.ItemPrices.Where(x => item.ItemPrices.Max(y => y.EffectiveDate) == x.EffectiveDate),
                        CurrentItemState = item.ItemReductions.Where(x => x.StartDate <= DateTime.Now && DateTime.Now <= x.EndDate)});

        return items;
    }

但是当我尝试这个并且我需要添加过滤器时,我无法按照我期望的方式添加它们。

    public dynamic GetCurrentItems(string filter = "", int categoryId = 1) {
        dynamic result;

        var categoryServices = new CategoryServices();

        IEnumerable<int> categoryIdAndChildCategoriesId = categoryServices.GetCategoryIdAndChildsId(categoryId);

        if (!string.IsNullOrWhiteSpace(filter))
        {
            result = this.GetAllCurrentItems().Where(x => ((string)(x.Item.Name)) == filter);
        }
        else if(categoryId != 1)
        {
            result = this.GetAllCurrentItems().Where(x => x.Item.ItemCategories.Any(x => categoryIdAndChildCategoriesId.Contains(x.CategoryId)));
        }

        return result;
    }

解决方案2:我也尝试过Tuple,我应该可以做这样的事情,但如果我在另一篇文章中理解,我无法创建从Linq到Entities的元组。我需要先查询所有项目,然后使用linq来反对创建我的元组。

解决方案3:我可以创建一个viewmodel或一个代表我需要的数据的新模型。我知道这会奏效,但我不明白它们会在两者之间的位置。如果它不是视图模型,则此信息不会以另一种方式进入视图,以查看仅包含当前信息的项目。 简而言之,这个问题可能有很多解决方案,但我需要帮助来了解哪种解决方案最好,为什么。

1 个答案:

答案 0 :(得分:0)

据我了解你,你想尽可能多地在数据库上做 - 这很好。你可以用这样的元组实现这个目标:

public IEnumerable<Tuple<Item,decimal, decimal>> GetAllCurrentItems(Expression<Func<Item, bool>> filterExpression){
    using(MyContext context = new MyContext())
    {
        var items = context.Items
                .Where(filterExpression)
                .Select(item => new Tuple<Item,decimal, decimal> ( 
                    item, 
                    item.ItemPrices.Where(x => item.ItemPrices.Max(y => y.EffectiveDate) == x.EffectiveDate),
                    item.ItemReductions.Where(x => x.StartDate <= DateTime.Now && DateTime.Now <= x.EndDate)});

        return items;
    }
}

并称之为:

public IEnumerable<Tuple<Item,decimal, decimal>> GetCurrentItems(string filter = "", int categoryId = 1) {
    dynamic result;

    var categoryServices = new CategoryServices();

    IEnumerable<int> categoryIdAndChildCategoriesId = categoryServices.GetCategoryIdAndChildsId(categoryId);

    if (!string.IsNullOrWhiteSpace(filter))
    {
        result = this.GetAllCurrentItems(x => ((string)(x.Item.Name)) == filter);
    }
    else if(categoryId != 1)
    {
        result = this.GetAllCurrentItems(x => x.Item.ItemCategories.Any(x => categoryIdAndChildCategoriesId.Contains(x.CategoryId)));
    }

    return result;
}