Reputation: 1463
I am fairly new to C# and .Net, so apologies if something doesn't make sense, I will try my best to explain my problem.
I have two methods which are basically going to use the similar query but with slight differences. So instead of repeating the query in both methods I created a third private method which will return the common part of the query and then the functions can add more clauses in query as they require.
Here is a generic function which returns the IQueryable
object with common part of the query
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
});
}
Following are the two method which are reusing the IQueryable
object
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();
}
Now GetSellerOffers
works just fine but GetDowngradableSellerOffers
throws a run time error with message The specified type member 'Sku' is not supported in LINQ to Entities.
. I asked around and one of the guys told me that I cannot add additional where
after adding a select
which uses a ViewModel
because then my records will be mapped to ViewModel
and LINQ
will attempt to look up props of ViewModel
instead of database columns.
Now I have two questions,
In the docs I read Entity Framework will only run query when I try to fetch the results with methods like ToList
and if I haven't done that why it wouldn't allow me to apply conditions on database fields/
How can I reuse the common query in my scenario?
Upvotes: 4
Views: 2593
Reputation: 1066
How about the following code:
(The type Offer
should be replaced by the type of the Elements that Db.Offers
holds)
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);
}
And then call it in GetDowngradableSellerOffers
like this:
public async Task<List<OfferViewModel>> GetDowngradableSellerOffers(int sellerId)
{
var query = GetOffersQueryForSeller(sellerId, (o) => o.Sku.Id == monthlySkuId);
return await query.ToListAsync();
}
Upvotes: 1