我在类中有一个方法,允许我根据一组客户指定的条件返回结果。该方法将Customer在前端指定的内容与来自数据库的集合中的每个项目进行匹配。如果客户未指定任何属性,则将attibute的ID传递给等于0的方法(数据库在所有以1为种子并且为增量的表上具有标识)。在这种情况下,应忽略该属性,例如,如果Customer未指定Location,则customerSearchCriteria.LocationID = 0将进入该方法。然后,匹配将匹配其他属性,并返回与其他属性匹配的所有位置,例如:
public IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
if(customerSearchCriteria.LocationID == 0)
{
return repository.GetAllPetsLinkedCriteria()
.Where(x => x.TypeID == customerSearchCriteria.TypeID &&
x.FeedingMethodID == customerSearchCriteria.FeedingMethodID &&
x.FlyAblityID == customerSearchCriteria.FlyAblityID )
.Select(y => y.Pet);
}
}
指定所有条件的代码如下所示:
private PetsRepository repository = new PetsRepository();
public IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
return repository.GetAllPetsLinkedCriteria()
.Where(x => x.TypeID == customerSearchCriteria.TypeID &&
x.FeedingMethodID == customerSearchCriteria.FeedingMethodID &&
x.FlyAblityID == customerSearchCriteria.FlyAblityID &&
x.LocationID == customerSearchCriteria.LocationID )
.Select(y => y.Pet);
}
我希望避免每次客户没有明确选择他们正在寻找的结果的属性时,有一整套 if和else语句来满足。我能做到这一点的最有效和最有效的方式是什么?
答案 0 :(得分:2)
未选择的标准始终为零,对吧?那么如何在字段等于标准或条件等于零的情况下获取行。
这应该有效
private PetsRepository repository = new PetsRepository();
public IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
return repository.GetAllPetsLinkedCriteria()
.Where(x => (customerSearchCriteria.TypeID == 0 || x.TypeID == customerSearchCriteria.TypeID)&&
(customerSearchCriteria.FeedingMethodID == 0 || x.FeedingMethodID == customerSearchCriteria.FeedingMethodID) &&
(customerSearchCriteria.FlyAblityID == 0 || x.FlyAblityID == customerSearchCriteria.FlyAblityID) &&
(customerSearchCriteria.LocationID == 0 || x.LocationID == customerSearchCriteria.LocationID))
.Select(y => y.Pet);
}
或者,如果这是您发现自己做了很多事情,您可以编写一个替代Where
扩展方法,该方法应用条件或通过(如果为零),并链接调用而不是具有一个条件标准。那么你每个查询只对标准== 0进行一次比较,而不是每个不匹配的行。我不确定是否值得 - 可能 - 边际性能提升,如果你想要性能提升,最好在数据库中应用过滤器。
无论如何,这是为了启发。 。
static class Extns
{
public static IEnumerable<T> WhereZeroOr<T>(this IEnumerable<T> items, Func<T, int> idAccessor, int id)
{
if (id == 0)
return items;
else
return items.Where(x => idAccessor(x) == id);
}
}
private PetsRepository repository = new PetsRepository();
public IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
return repository.GetAllPetsLinkedCriteria()
.WhereZeroOr(x => x.TypeID, customerSearchCriteria.TypeID)
.WhereZeroOr(x => x.FeedingMethodID, customerSearchCriteria.FeedingMethodID)
.WhereZeroOr(x => x.FlyAblityID, customerSearchCriteria.FlyAblityID)
.WhereZeroOr(x => x.LocationID, customerSearchCriteria.LocationID);
}
答案 1 :(得分:2)
看起来您正在使用存储过程,并且您首先获取所有记录然后进行过滤。我建议你在存储过程级别进行过滤,让数据库完成繁重的任务,并且你需要做的任何微过滤都会更容易。在你的sproc中,让你的参数默认为NULL并使你的属性可以为条件对象设置为空,这样你就可以传入值,并且(应该)纠正sproc以使用这些空值,即
private PetsRepository repository = new PetsRepository();
public IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
return repository.GetAllPetsLinkedCriteria(customerSearchCriteria.TypeID,customerSearchCriteria.FeedingMethodID,customerSearchCriteria.FlyAblityID,customerSearchCriteria.LocationID).ToList();
}
答案 2 :(得分:2)
我没有看到优雅的解决方案。可能是这样的:
IEnumerable<Pet> FindPetsMatchingCustomerCriteria(CustomerPetSearchCriteria customerSearchCriteria)
{
return repository.GetAllPetsLinkedCriteria()
.Where(x =>
Check(x.TypeID, customerSearchCriteria.TypeID) &&
Check(x.FeedingMethodID, customerSearchCriteria.FeedingMethodID) &&
Check(x.FlyAblityID, customerSearchCriteria.FlyAblityID) &&
Check(x.LocationID, customerSearchCriteria.LocationID))
.Select(x => x.Pet);
}
static bool Check(int petProperty, int searchCriteriaProperty)
{
return searchCriteriaProperty == 0 || petProperty == searchCriteriaProperty;
}