如何在选择视图模型时在IQueryable中添加新的where条件?

时间:2018-05-16 06:47:00

标签: c# asp.net .net

我对C#和.Net相当新,所以如果事情没有意义,我会道歉,我会尽力解释我的问题。

我有两种方法基本上会使用类似的查询,但略有不同。因此,我没有在两个方法中重复查询,而是创建了第三个私有方法,它将返回查询的公共部分,然后函数可以根据需要在查询中添加更多子句。

这是一个泛型函数,它返回IQueryable对象与查询的公共部分

private IQueryable<OfferViewModel> GetOffersQueryForSeller(int sellerId)
{
    return Db.Offers
        .Where(o => o.Sku.SellerId == sellerId && o.IsActive && !o.IsDiscontinued)
        .Select(o => new OfferViewModel
        {
            Id = o.Id,
            Name = o.Sku.Name,
            ImageUrl = o.Sku.ImageUrl ?? o.Sku.Upcq.Upc.ImageUrl,
            QuantityName = o.Sku.QuantityName
        });
} 

以下是重用IQueryable对象

的两种方法
public async Task<List<OfferViewModel>> GetSellerOffers(int sellerId)
{
    var query = GetOffersQueryForSeller(sellerId);
    return await query.ToListAsync();
}

public async Task<List<OfferViewModel>> GetDowngradableSellerOffers(int sellerId)
{
    var query = GetOffersQueryForSeller(sellerId);
    return await query
        .Where(o => o.Sku.Id == monthlySkuId)
        .ToListAsync();
}

现在GetSellerOffers工作正常,但GetDowngradableSellerOffers会因邮件The specified type member 'Sku' is not supported in LINQ to Entities.而引发运行时错误。我四处询问,其中一个人告诉我,在添加使用where的{​​{1}}之后我无法添加额外的select因为我的记录将被映射到ViewModel并且ViewModel将尝试查找LINQ而不是数据库列的道具。

现在我有两个问题,

  1. 在我阅读的文档中,当我尝试使用ViewModel等方法获取结果时,实体框架将仅运行查询,如果我没有这样做,为什么它不允许我应用条件在数据库字段/

  2. 如何在我的方案中重用常见查询?

1 个答案:

答案 0 :(得分:1)

以下代码如何:
(类型Offer应替换为Db.Offers持有的元素类型

private IQueryable<OfferViewModel> GetOffersQueryForSeller(int sellerId, Func<Offer,bool> whereExtension)
{
    return Db.Offers
        .Where(o => ... && whereExtension.Invoke(o))
        .Select(o => new OfferViewModel { ... });
}

private IQueryable<OfferViewModel> GetOffersQueryForSeller(int sellerId)
{
    return GetOffersQueryForSeller(sellerId, (o) => true);
}

然后在GetDowngradableSellerOffers中调用它:

public async Task<List<OfferViewModel>> GetDowngradableSellerOffers(int sellerId)
{
    var query = GetOffersQueryForSeller(sellerId, (o) => o.Sku.Id == monthlySkuId);
    return await query.ToListAsync();
}