【问题标题】:Filtering search using multiple dropdowns in MVC gives null Model在 MVC 中使用多个下拉列表过滤搜索会给出空模型
【发布时间】:2020-04-27 16:59:33
【问题描述】:

我目前正在构建一个 MVC 应用程序,我正在尝试根据选定的下拉列表显示汽车列表。我不希望用户必须选择多个下拉列表进行搜索,我希望代码能够通过下拉列表的任意组合进行搜索。我开始用 If else 语句编写代码,但我认为这不是最佳实践,所以我做了一些研究并找到了一种不同的方法来过滤我的结果。我遇到的问题是我在模型中得到了一个空值。

这是我的模特

    public partial class Car 
{

    private Ignition_Hub_DBEntities Context;

    public IQueryable<Car> GetProducts(Car searchModel)
    {
        var result = Context.Cars.AsQueryable();
        if (searchModel != null)
        {
            if (searchModel.CarLotID.HasValue)
                result = result.Where(x => x.CarLotID == searchModel.CarLotID);
            if (searchModel.Available.HasValue)
                result = result.Where(x => x.Available == searchModel.Available);
            if (searchModel.ModelID.HasValue)
                result = result.Where(x => x.ModelID == searchModel.ModelID);
             if (searchModel.Model.MakeID.HasValue)
                return result;
            result = result.Where(x => x.Model.MakeID == searchModel.Model.MakeID);
            return result;
        }
        return result;
    }
        public Car()
    {
        Context = new Ignition_Hub_DBEntities();

    }
    public int? CarID { get; set; }
    public string Year { get; set; }

    public string Notes { get; set; }
    public bool? Available { get; set; }
    public string VinNumber { get; set; }
    public int? CarLotID { get; set; }
    public int? ModelID { get; set; }

    public virtual Model Model { get; set; }
    public virtual CarLot CarLot { get; set; }
}

这是我的控制器

        public ActionResult DisplaySearchResults(Car searchModel)
    {

        var business = new Car();
        var model = business.GetProducts(searchModel);
        return PartialView("_Index", model);
}

现在我在if (searchModel.Model.MakeID.HasValue) 上收到错误消息 错误是'Object reference not set to an instance of an object.' 在此先感谢您的帮助!如果有更好的方法来实现这一点,请指教。谢谢!

【问题讨论】:

    标签: c# asp.net .net asp.net-mvc entity-framework


    【解决方案1】:

    你需要确保搜索模型的Model属性不为空并且已经传递给动作,那么在搜索时你需要确保linq查询中元素的Model属性不为空,然后将搜索模型的MakeID 属性与linq 查询中元素的MakeID 属性进行比较。比如你要根据Model中的MakeID进行搜索,如果指定了,则需要将代码改成如下:

    if (searchModel.Model !=null && searchModel.Model.MakeID.HasValue)
        result = result.Where(x => x.Model !=null && 
            x.Model.MakeID == searchModel.Model.MakeID);
    

    但是,如果您关注 this post,通常最好遵循以下建议:

    • 不要将实体模型用作 POCO 搜索模型。
    • 不要将业务逻辑放在您的 POCO 类中。
    • 如果您要根据 MakeID 进行搜索,请将其直接包含在 POCO 搜索模型中。

    示例

    我将扩展链接帖子中的示例,因此Product 也具有Category 属性,我们有兴趣根据CategoryName 以及其他一些属性进行搜索:

    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    public class Product
    {
        public int Id { get; set; }
        public int Price { get; set; }
        public string Name { get; set; }
        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
    

    您可以创建一个ProductSearchModel 类并根据它们放置一些您想要搜索的字段:

    public class ProductSearchModel
    {
        public int? Id { get; set; }
        public int? PriceFrom { get; set; }
        public int? PriceTo { get; set; }
        public string Name { get; set; }
        public string CategoryName { get; set; }
    }
    

    然后你可以把你的搜索逻辑放在ProductBusinessLogic类中:

    public class ProductBusinessLogic
    {
        private YourDbContext Context;
        public ProductBusinessLogic()
        {
            Context = new YourDbContext();
        }
    
        public IQueryable<Product> GetProducts(ProductSearchModel searchModel)
        {
            var result = Context.Products.AsQueryable();
            if (searchModel != null)
            {
                if (searchModel.Id.HasValue)
                    result = result.Where(x => x.Id == searchModel.Id);
                if (!string.IsNullOrEmpty(searchModel.Name))
                    result = result.Where(x => x.Name.Contains(searchModel.Name));
                if (searchModel.PriceFrom.HasValue)
                    result = result.Where(x => x.Price >= searchModel.PriceFrom);
                if (searchModel.PriceTo.HasValue)
                    result = result.Where(x => x.Price <= searchModel.PriceTo);
                if (!string.IsNullOrEmpty(searchModel.CategoryName))
                    result = result.Where(x => x.Category !=null && 
                        x.Category.Name.Contains(searchModel.Name));
            }
            return result;     
        }
    }
    

    【讨论】:

    • 非常感谢!您在此答案中的初始 if 语句解决了我的问题。我会听取您的建议,以便更好地使用 POCO。但是,我的表格中有一个复选框,如果汽车可用,则选中该复选框,如果汽车不可用,则未选中。添加此代码后,复选框变成了选择下拉菜单。有什么理由吗?
    • 没问题:) 添加此代码后,复选框变成了选择下拉菜单 → 暂时不知道:\
    猜你喜欢
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2023-03-26
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多