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」という名前のモデルに対して検索を試みます (これは、「Ads」を意味します)。私の言語)

ResultadosPesquisaController.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>

*私の問題は * ResultadosPesquisaController のクエリは、3 つすべてのドロップダウン リストに値を入力した場合にのみ結果を取得します。これを達成しますか?

LINQ Dynamic Query Libraryを使用して、1つの可能な方法を考えました。

scott gu による LINQ 動的クエリ ライブラリの使用

そうすれば、最初のインデックス アクションで一連の if ステートメント (あまりエレガントではない) を使用してクエリを作成し、動的 ​​LINQ で事前に作成されたクエリを使用して実行する 2 番目のアクションにリダイレクトできます。

これを達成するためのよりエレガントな方法がある場合は、私にアドバイスしてください。

ありがとうございました。

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 に答える