在存储库设计模式中过滤数据集C#

时间:2018-04-18 15:21:36

标签: c# entity-framework linq repository-pattern

我有一个给定的下面的查询,这是完美的

SELECT
    MAX(WarehouseId)       AS WareHouseId, 
    MAX(CompanyId)         AS CompanyId, 
    MAX(ProductId)         AS ProductId,
    SUM(AvailableQuantity) AS AvailableQuantity,
    PurchaseItemPrice 
FROM
    PurchaseItem 
WHERE
    CompanyId = 1 
GROUP BY
    PurchaseItemPrice
ORDER BY
    MAX(ProductId) ASC

我需要转换为以下格式而不是linq。我真的不知道下面给出的格式名称是什么。还请告诉我我们可以称之为这种格式,如果这不是一个获取数据的好方法,请提出更好的建议,因为我是存储库设计模式的新手。

unitOfWork.PurchaseItemRepository.DataSet
    .Where( x => x.CompanyId == id )
    .ToList()
    .GroupBy( x => x.PurchaseItemPrice )
    .Select( x =>
        x.Max( y => new
        {
            y.WarehouseId,
            y.CompanyId,
            y.ProductId,
            y.AvailableQuantity
        } )
    );

public IRepository<PurchaseItem> PurchaseItemRepository
{
    get
    {
        if (_PurchaseItemRepository == null)
        {
            dbContext.Configuration.ProxyCreationEnabled = false;
            _PurchaseItemRepository = new Repository<PurchaseItem>(dbContext);
        }
        return _PurchaseItemRepository;
    }
}

ProductItem是一个实体

此外,当我执行上面的代码时,它会显示以下错误。

  

mscorlib.dll中出现“System.ArgumentException”类型的异常,但未在用户代码中处理。附加信息:至少有一个对象必须实现IComparable。

2 个答案:

答案 0 :(得分:0)

You need to have a way to determine the max. What are you doing max on how is the compiler going to know what property you want to use max on?

you probably want to grab the MAX on each one of those properties individually. I.e

 unitOfWork.PurchaseItemRepository.DataSet
      .Where(x => x.CompanyId == id).ToList()
      .GroupBy(x => x.PurchaseItemPrice)
      .Select(x => new {
        WarehouseId = x.OrderByDescending(v => v.WarehouseId).FirstOrDefault(),
        CompanyId = x.OrderByDescending(v => v.CompanyId).FirstOrDefault(),
        //Do the rest here 
      }).OrderBy( output => output.ProductId )
      .ToList();

As a side note you probably shouldn't be calling ToList() this will materialize the whole table. You should work with IQuerables instead so you can filter without pulling the whole table

答案 1 :(得分:0)

(顺便说一下,你不需要在Linq和Entity Framework中使用Repository(反)模式,因为DbContext 存储库。注意创建类来保存预定义的Linq查询与存储库不同。我也不相信工作单元模式对于实体框架有很大用处,或者作为DbContext块中的短暂using交易也履行了这个角色)

var list = dbContext.PurchaseItems
    .Where( x => x.CompanyId == 1 )
    .GroupBy( x => x.PurchaseItemPrice )
    .Select( grp => new {
        PurchaseItemPrice = grp.Key,
        WarehouseId       = grp.Max( x => x.WarehouseId ),
        CompanyId         = grp.Max( x => x.CompanyId ),
        ProductId         = grp.Max( x => x.ProductId ),
        AvailableQuantity = grp.Sum( x => x.AvailableQuantity ),
    } )
    .OrderBy( output => output.ProductId )
    .ToList();
由于在list调用中使用了匿名类型,

var将需要使用推断类型(.Select)。如果您将其更改为自定义记录类型,则可以改为使用List<MyOutputRecordType>