1

我正在使用 asp.net mvc3,我将实现高级搜索
这是我的高级搜索表单

 @using (Html.BeginForm("AdvanceSearch","Coupon",FormMethod.Post))
    {
        @Html.ValidationSummary(true)
        <fieldset>

            <div class="editor-label">
                @Html.LabelFor(model => model.AdvanceSearch.CouponName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.AdvanceSearch.CouponName)
                @Html.ValidationMessageFor(model => model.AdvanceSearch.CouponName)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.AdvanceSearch.Category)
            </div>
            <div class="editor-field">
                @Html.DropDownList("categories", new SelectList(Model.AdvanceSearch.Category.OrderBy(c=>c.Name).Select(c => c.Name)), "--- Select Categories ---")
                @Html.ValidationMessageFor(model => model.AdvanceSearch.Category)
            </div>
            <div class="editor-label">

                <div class="editor-label">
                    @Html.LabelFor(model => model.AdvanceSearch.CreateDate)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.AdvanceSearch.CreateDate, new { @class = "picker" })
                    @Html.ValidationMessageFor(model => model.AdvanceSearch.CreateDate)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.AdvanceSearch.ExpiredDate)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.AdvanceSearch.ExpiredDate, new { @class = "picker" })
                    @Html.ValidationMessageFor(model => model.AdvanceSearch.ExpiredDate)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.AdvanceSearch.PublishDate)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.AdvanceSearch.PublishDate, new { @class = "picker" })
                    @Html.ValidationMessageFor(model => model.AdvanceSearch.PublishDate)
                </div>
                @Html.LabelFor(model => model.AdvanceSearch.Company)
            </div>
            <div class="editor-field">
                @Html.DropDownList("companies", new SelectList(Model.AdvanceSearch.Company.OrderBy(c=>c.Name).Select(c => c.Name)), "--- Select Companies ---")
                @Html.ValidationMessageFor(model => model.AdvanceSearch.Company)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.AdvanceSearch.Description)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.AdvanceSearch.Description)
                @Html.ValidationMessageFor(model => model.AdvanceSearch.Description)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.AdvanceSearch.IsPublish)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.AdvanceSearch.IsPublish)
                @Html.ValidationMessageFor(model => model.AdvanceSearch.IsPublish)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.AdvanceSearch.Active)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.AdvanceSearch.Active)
                @Html.ValidationMessageFor(model => model.AdvanceSearch.Active)
            </div>

            <p>
                <input type="submit" value="Search" />
            </p>
        </fieldset>
    }

现在的问题是我有以下情况

  • 如果只给出 CouponName 则返回所有包含指定名称的优惠券
  • 如果从公司列表中选择了任何公司,那么我们将搜索该公司的所有具有指定名称的优惠券将被返回
  • 如果从类别列表中选择了任何类别,那么我们将搜索该类别中具有指定名称的所有优惠券将被返回
  • 如果选择了所有三个日期中的任何日期,那么我们将在该日期之前过滤优惠券

现在我很困惑,最好的方法是什么,我应该执行if else条件,switch还是什么?

4

1 回答 1

0

不确定是否有“最佳方法”。这完全取决于您如何应用过滤器。

我使用 LINQ 来应用过滤器,并且喜欢使用基本表达式编写过滤器构造,然后为每个提供的过滤器选择使用 AND 表达式。我使用一些扩展方法使这更容易。然后您可以逐步构建您的过滤器表达式,并且随着它变得更加复杂,您可以相应地实施步骤。每个基本步骤都会有一个 if 检查以查看是否指定了特定部分,以及是否将其附加到基本表达式。

// Example of service for applying filter
public GetProductsResponse GetProducts(GetProductsRequest request)
{
    // base expression is true, ie always returns everything
    Expression<Func<ProductEntity, bool>> filterExpression = i => true;

    // subsequent filters narrow base expression results
    if (!request.IncludeDeleted)
        filterExpression = filterExpression.And(i => i
            .IsDeleted == false);

    // I like to use nullable types so that I can check whether a parameter is specified or not
    if (request.CouponName != null)
        filterExpression = filterExpression.And(i => 
            i.CouponName == request.CouponName.Value);

    if (request.Company!= null)
        filterExpression = filterExpression.And(i => 
            i.Company== request.Company.Value);

    // etc.

    var products = _dataContext.Products.Where(filterExpression);

    // you probably want to transform products into some sort of model specific class

    return new GetProductsRequest
    {
        products = products;
    };
}


// Extension methods for Linq And and Or helpers
public static class Utility
{
    public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
    {
        // build parameter map (from parameters of second to parameters of first)
        var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

        // replace parameters in the second lambda expression with parameters from the first
        var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

        // apply composition of lambda expression bodies to parameters from the first expression 
        return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.And);
    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.Or);
    }
}
于 2012-11-23T11:13:02.810 回答