匹配客户在前端选择的搜索属性

时间:2012-11-11 08:42:47

标签: c# linq

我在类中有一个方法,允许我根据一组客户指定的条件返回结果。该方法将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语句来满足。我能做到这一点的最有效和最有效的方式是什么?

3 个答案:

答案 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;
}