2

我正在尝试使用具有多个下拉列表的表单执行搜索以限制搜索值,下拉列表通过视图模型填充。

视图模型:PesquisaHomeViewModel.cs

using System; 
using System.Collections.Generic; 
using System.Linq;
using System.Web; 
using MinisPT.Models;

namespace MinisPT.ViewModels {
     public class PesquisaHomeViewModel
     {
        public List<Marca> Marcas { get; set; }       
         public List<Modelo> Modelos { get; set; }
         public List<EstadoProduto> EstadosProdutos { get; set; }
     } 
}

这是具有以下形式的视图的一部分:Home/Index.cshtml

@using (Html.BeginForm("Index", "ResultadosPesquisa", FormMethod.Get))
            {
                @Html.ValidationSummary(true)                 
                <div id="coluna1">
                <div class="coluna1_titulo">Marca</div>
                <div class="coluna1_DropDownList">
                    @Html.DropDownListFor(m => m.Marcas, new SelectList(Model.Marcas, "MarcaNome", "MarcaNome"), String.Empty)
                </div>
                <div class="coluna1_titulo">Modelo</div>
                <div class="coluna1_DropDownList">
                    @Html.DropDownListFor(md => md.Modelos, new SelectList(Model.Modelos, "ModeloNome", "ModeloNome"), String.Empty)
                </div>
                <div class="coluna1_titulo">Estado</div>
                <div class="coluna1_DropDownList">
                    @Html.DropDownListFor(e => e.EstadosProdutos, new SelectList(Model.EstadosProdutos, "EstadoProdutoTipo", "EstadoProdutoTipo"), String.Empty)
                </div>
                <span>
                    <input type="submit" value="Pesquisar" class="botaoPesquisa" />
                </span>                
           }

正如您通过提交所看到的,我调用“ResultadosPesquisa”控制器的索引操作,在该控制器中,我使用表单的参数并尝试对名为“Anuncios”的模型进行搜索(这意味着“广告”在我的语言)

结果PesquisaController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using System.Data.Entity;
using MinisPT.Models;
using MinisPT.ViewModels;

namespace MinisPT.Controllers
{
    public class ResultadosPesquisaController : Controller
    {
        MinisPTEntities db = new MinisPTEntities();

        //
        // GET: /ResultadosPesquisa/
        public ActionResult Index(string Marcas, string Modelos, string EstadosProdutos)
        {
            var query = from m in db.Anuncios.Include(a => a.Marca).Include(a => a.Modelo)
                        where m.Marca.MarcaNome == Marcas
                        where m.Modelo.ModeloNome == Modelos
                        where m.EstadoProduto.EstadoProdutoTipo == EstadosProdutos
                        select m;

            return View(query.ToList());
        }
    }
}

我应该稍后显示结果,它调用视图 ResultadosPesquisa/Index.cshtml:

@model IEnumerable<MinisPT.Models.Anuncio>

... (html stuff in here) 

<table>
    <tr>
        <th>
            Marca
        </th>
        <th>
            Modelo
        </th>
        <th>
            Estado
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(a => item.Marca.MarcaNome)
        </td>
        <td>
            @Html.DisplayFor(a => item.Modelo.ModeloNome)
        </td>
        <td>
            @Html.DisplayFor(a => item.EstadoProduto.EstadoProdutoTipo)
        </td>
    </tr>
}

</table>

*我的问题是 *如果我将值放在所有 3 个下拉列表中,则 ResultadosPesquisaController 上的查询只会让我得到结果,如果我只在其中一个下拉列表中选择一个值,则不会返回任何值,但我想让所有下拉列表都是可选的,我怎么能达到这个?

我想到了一种可能的方法,使用 LINQ 动态查询库,

使用 scott gu 的 LINQ 动态查询库

这样我就可以在第一个索引操作上构造查询,使用一堆 if 语句(不是很优雅)并重定向到第二个操作,在该操作中我将使用带有动态 LINQ 的预构建查询并执行它。

如果有更优雅的方式来完成这个,请告诉我。

谢谢你。

4

1 回答 1

3

您将 Linq 结构化的方式就像&&操作一样堆叠。您需要将其更改为:

var query = from m in db.Anuncios.Include(a => a.Marca).Include(a => a.Modelo)
            where m.Marca.MarcaNome == Marcas ||
                m.Modelo.ModeloNome == Modelos ||
                m.EstadoProduto.EstadoProdutoTipo == EstadosProdutos
            select m

这应该返回任何选择的结果。

编辑:
根据您在下面的评论,您最好使用扩展方法来堆叠它们。由于这将涉及数据上下文(我的假设基于db.Anuncios),因此这些调用将被推迟到实际使用时。

var query = from m in db.Anuncios.Include(a => a.Marca).Include(a => a.Modelo)
            select m;

if (!string.IsNullOrWhitespace(Marcas))
    query = query.Where(m => m.Marca.MarcaNome == Marcas);

if (!string.IsNullOrWhitespace(Modelos))
    query = query.Where(m => m.Modelo.ModeloNome == Modelos);

if (!string.IsNullOrWhitespace(EstadoProdutoTipo))
    query = query.Where(m => m.EstadoProduto.EstadoProdutoTipo == EstadosProdutos);

无论 m 是什么,最终结果仍然是 an IQueryable<T>,但是因为 where 子句在实际调用之前不会被添加。这可以在您使用的查询语法中完成,但它变得非常丑陋和复杂。这看起来更干净,更容易维护 IMO。

于 2012-06-20T10:40:37.473 回答