I am getting products using given parameters (name of real entity and columns changed for illustration purposes),
public IQueryable<Product> GetProductsByPara(string price, string weight, string dimensions, string trend)
{
var result = dbContext.Products.Where(a =>
a.Price.ToLower().Equals(price.ToLower()) &&
a.Weight.ToLower().Equals(weight.ToLower()) &&
a.Dimensions.ToLower().Equals(dimensions.ToLower()) &&
a.Trend.ToLower().Equals(trend.ToLower()));
if (result.Any())
{
return result;
}
if (!string.IsNullOrWhiteSpace(price))
{
result = dbContext.Products.Where(a =>
a.Price.ToLower().Equals(price.ToLower()) &&
a.Weight.ToLower().Equals(weight.ToLower()) &&
a.Trend.ToLower().Equals(trend.ToLower()));
if (result.Any())
{
return result;
}
}
if (!string.IsNullOrEmpty(dimensions))
{
result = dbContext.Products.Where(a =>
a.Dimensions.ToLower().Equals(dimensions.ToLower()) &&
a.Weight.ToLower().Equals(weight.ToLower()) &&
a.Trend.ToLower().Equals(trend.ToLower()));
if (result.Any())
{
return result;
}
}
return result;
}
2 Answers 2
Here is an approach to get rid of some of the redundancy:
First write an extension Method
static IQueryable<Product> FilterForParameters
(this IQueryable<Product> query, string price, string weight, string dimensions, string trend)
{
if (price != null)
query = query.Where(p => p.Price.ToLower().Equals(price.ToLower()));
if (weight != null)
query = query.Where(p => p.Weight.ToLower().Equals(weight.ToLower()));
if (dimensions != null)
query = query.Where(p => p.Dimension.ToLower().Equals(dimensions.ToLower()));
if (trend != null)
query = query.Where(p => p.Trend.ToLower().Equals(trend.ToLower()));
return query;
}
Then change your method
public IQueryable<Product> GetProductsByPara(string price, string weight, string dimensions, string trend)
{
var products = dbContext.Products;
var productsFilterdByAll = products.FilterForParameters(price, weight, dimensions, trend);
if (productsFilterdByAll.Any())
return productsFilterdByAll;
var productsFilterdByAllButDimnensions = products.FilterForParameters(price, weight, null, trend);
if (productsFilterdByAllButDimnensions.Any())
return productsFilterdByAllButDimnensions;
var productsFilterdByAllButPrice = products.FilterForParameters(null, weight, dimensions, trend);
return productsFilterdByAllButPrice;
}
Depending on the context, it would also be a good idea to check your parameters for null at the beginning of the method.
use ternary operator
as condition ? true : false;
public IQueryable<Product> GetProductsByPara(string price, string weight, string dimensions, string trend)
{
return dbContext.Products.Where(a =>
a.Price.Equals(!string.IsNullOrEmpty(dimensions) ? a.Price : price,StringComparison.OrdinalIgnoreCase)
&& a.Weight.Equals(weight, StringComparison.OrdinalIgnoreCase)
&& a.Dimensions.Equals(!string.IsNullOrWhiteSpace(price) ? a.Dimensions : dimensions, StringComparison.OrdinalIgnoreCase)
&& a.Trend.Equals(trend, StringComparison.OrdinalIgnoreCase)
);
}
It is unnecessary to repeat:
if (result.Any())
{
return result;
}
.
Also, using StringComparison.OrdinalIgnoreCase
would be much more appropriate than ToLower()
-
1\$\begingroup\$ OP is changing the content of
result
. So checking forresult.Any()
multiple times is actually a reasonable thing to do. \$\endgroup\$Tim Pohlmann– Tim Pohlmann2019年12月17日 14:36:51 +00:00Commented Dec 17, 2019 at 14:36
strings
? That makes no sense. \$\endgroup\$