繁体   English   中英

从 ASP.NET MVC 5、C# 和实体框架中的下拉列表选择中过滤数据

[英]Filtering data from a dropdown list selection in ASP.NET MVC 5, C# and Entity Framework

我有一个通过实体框架访问的数据库,我从中获取数据。 我有两个下拉列表,我希望能够根据用户选择过滤我的数据。 例如,我在数据库中的表名为Products ,在一个下拉列表中,我希望能够按公司过滤产品,而对于另一个下拉列表,我希望能够按类别过滤产品。 或者,如果从两个下拉列表中进行选择,则根据该条件过滤数据。

My Products表包含公司的CompanyID列和CategoryID的 CategoryID。 它们都是其他表的外键(如下所示):

  1. 对于Products表中的CompanyID ,引用的表是Companies ,其中包含CompanyID (主键)和Brand Name (下拉列表中显示的内容)列

  2. 对于Products表中的CategoryID ,引用的表称为ItemCategories ,其中包含CategoryID (主键)和Category (下拉列表中显示的内容)列

注意:我更喜欢保持这种方式,因为公司和项目类别可以定期更改,我喜欢能够更新表格而不是代码,但我认为它们被读取为 int 并且不能转换为字符串(在至少那是我的错误信息所说的)这就是为什么我认为我很难过。

我已经尝试了我能找到的所有东西的 500 种不同的变体,但无济于事。 我得到的最接近的是我在一个下拉列表中选择了一个项目,它返回了一个包含 0 个结果的列表。 我尝试过的所有其他东西都会给我错误消息,或者当我单击过滤器时它根本不做任何事情。 让我感到困惑的是我见过的很多例子在他们的代码中使用了这样的东西:

products = products.Where(x => x.CompanyID == (prodCompany));

它不会让我使用 == 因为它

不能应用于 int 类型的操作数? 和字符串

在我展示我的代码之前,我要补充的最后一点是,我有数百种产品,并且必须为它们使用分页列表,否则加载时间太长并冻结我。 使过滤工作的另一个棘手的部分是必须如何合并分页列表。 我让它工作得很好,但是当它没有过滤器时,它目前按 ProductID 的 OrderBy 方法排序。 我不确定这是否会影响我的结果,因为我想按 CompanyID 或 CategoryID 过滤(但希望它仍然按 ProductID 对过滤后的结果进行排序)?

最后总结:我正在使用带有实体框架和 C# 的 ASP.NET MVC 5,我希望能够根据从公司列表下拉列表或类别列表下拉列表中的选择在“索引”视图中过滤我的产品表中的数据(或两者),如果没有选择,它会显示所有产品(带有分页列表)。 这是我目前的代码:

我的模型类Product

public partial class Product
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Product()
    {
        this.ProductOrders = new HashSet<ProductOrder>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Product ID")]
    public int ProductID { get; set; }
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date")]
    public Nullable<System.DateTime> Date_Entered { get; set; }
    [Display(Name = "Product Code")]
    public string Product_Code { get; set; }
    public string Description { get; set; }
    [Display(Name = "Company")]
    public Nullable<int> CompanyID { get; set; }
    [AllowHtml]
    [Display(Name = "Category")]
    public Nullable<int> CategoryID { get; set; }
    [Display(Name = "Amt In Stock")]
    public Nullable<int> Amt_In_Stock { get; set; }
    [Display(Name = "Qty Available")]
    public Nullable<int> Qty_Available { get; set; }
    [Display(Name = "Image")]
    public string ImageUrl { get; set; }

    public virtual Company Company { get; set; }
    public virtual ItemCategory ItemCategory { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<ProductOrder> ProductOrders { get; set; }
}

这是我的ProductsController

namespace AMS_ITAMSdb.Controllers
{
    public class ProductsController : Controller
    {
        private ItamsEntities db = new ItamsEntities();

        // GET: Products
        public ActionResult Index(string prodCompany, string prodCategory, int? page)
        {
            ViewBag.prodCompany = new SelectList(db.Companies, "CompanyID", "Brand_Name");
            ViewBag.prodCategory = new SelectList(db.ItemCategories, "CategoryID", "Category");

            var prod = from p in db.Products
                       select p;

            if (!String.IsNullOrEmpty(prodCompany))
            {
                //Filter results based on company selected.
                var pageNumber = page ?? 1;
                var pageSize = 15;
                prod = prod.Where(x => x.CompanyID.Equals(prodCompany));
                var product = db.Products.OrderBy(x => x.ProductID).ToPagedList(pageNumber, pageSize);
                return View(product);
            }
            if (!String.IsNullOrEmpty(prodCategory))
            {
                //Filter results based on company selected.
                var pageNumber = page ?? 1;
                var pageSize = 15;
                prod = prod.Where(x => x.CategoryID.Equals(prodCategory));
                var product = db.Products.OrderBy(x => x.ProductID).ToPagedList(pageNumber, pageSize);
                return View(product);
            }
            else
            //var product = db.Products.OrderBy(x=>x.ProductID).ToList();
            {
                var pageNumber = page ?? 1;
                var pageSize = 15;
                var product = db.Products.OrderBy(x => x.ProductID).ToPagedList(pageNumber, pageSize);
                return View(product);
            }
        }
    }
}

最后我的索引视图:

@using AMS_ITAMSdb.Models;
@using PagedList;
@using PagedList.Mvc;
@model PagedList.IPagedList<Product>

@{
    ViewBag.Title = "Index";
}

<h2>Products</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>

@using (Html.BeginForm("Index", "Products", FormMethod.Get))
{
<p>
    Company: @Html.DropDownList("prodCompany", "All")

    Category: @Html.DropDownList("prodCategory", "All")
    <input type="submit" value="Filter" />
</p>
}

<table class="table">
    <tr>
        <th>
            Date
        </th>
        <th>
            Product Code
        </th>
        <th>
            Description
        </th>
        <th>
            Amt In Stock
        </th>
        <th>
            Qty Available
        </th>
        <th>
            Image
        </th>
        <th>
            Company
        </th>
        <th>
            Category
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Date_Entered)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Product_Code)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Amt_In_Stock)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Qty_Available)
            </td>
            <td>
                <img src="~/Images/@item.ImageUrl" width="100" height="100" />
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Company.Brand_Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ItemCategory.Category)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.ProductID }) |
                @Html.ActionLink("Details", "Details", new { id = item.ProductID }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.ProductID })
            </td>
        </tr>
    }
</table>
<link href="~/Content/PagedList.css" rel="stylesheet" />
<div></div>
(Page @(Model.PageCount < Model.PageNumber ? 0: Model.PageNumber)/@Model.PageCount)

    @Html.PagedListPager(Model, page => Url.Action("Index", new { page = page })) 

经过近两周的努力试图解决这个问题,我终于通过尝试我在另一个问题上看到的东西来解决这个问题:我找到的下拉列表选择值 我的代码非常接近,最终只是一个小调整,这就是我认为会发生的事情。 无论如何,我找到的修复是在我的控制器上,我将 .ToString() 添加到我的过滤器中,这允许我使用字符串中的 int 并将“Equals”更改为“Contains”。 我做的其他几个小改动是我添加了另一个字符串(字符串 currentFilter)并添加了一个 if 语句。 我在控制器中更改的新代码是:

    if (prodCompany != null)
            {
                page = 1;
            }
            else
            {
                prodCompany = currentFilter;
            }
            ViewBag.currentFilter = prodCompany;           

            var prod = from p in db.Products
                           select p;

            if (!String.IsNullOrEmpty(prodCompany))
            {
            //Filter results based on company selected.
                var pageNumber = page ?? 1;
                var pageSize = 15;
                prod = prod.Where(p => p.CompanyID.ToString().Contains(prodCompany));
                return View(prod.OrderBy(p => p.ProductID).ToPagedList(pageNumber, pageSize));
            }
            //var product = db.Products.OrderBy(x=>x.ProductID).ToList();
            {
                var pageNumber = page ?? 1;
                var pageSize = 15;
                var product = db.Products.OrderBy(p => p.ProductID).ToPagedList(pageNumber, pageSize);
                return View(product);
            }
        }

在我的索引视图中,我只需要在页面元素的底部做一​​个微小的改变:

@Html.PagedListPager(Model, page => Url.Action("Index", new { page, currentFilter = ViewBag.currentFilter }))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM