You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET/C# API查询时忽略INT类型空值的实现方法

实现忽略空值INT参数的MongoDB查询过滤

我用.NET/C#开发API,现有一个查询MongoDB的服务函数,当前所有过滤条件强制要求传入非空值,但需要实现当INT类型过滤参数为null时忽略该条件(当作通配符使用)。

现有代码

服务查询函数

public async Task<List<Item>> GetAsync(RequestParameters requestParameters) =>
        await _itemsCollection.Find(item => (item.item_description.Contains(requestParameters.FilterDescString) ||
                                            item.item_adddesc.Contains(requestParameters.FilterDescString)) &&
                                            item.item_id.Equals(requestParameters.FilterItemIdInt) &&
                                            item.item_amount.Equals(requestParameters.FilterAmountInt) &&
                                            item.item_width.Equals(requestParameters.FilterWidthInt) &&
                                            item.item_height.Equals(requestParameters.FilterHeightInt) &&
                                            item.item_weight.Equals(requestParameters.FilterWeightInt) &&
                                            item.item_aunumber.Contains(requestParameters.FilterAunumberString))
    .SortByDescending(i => i.item_id).Skip((requestParameters.PageNumber)* requestParameters.PageSize).Limit(requestParameters.PageSize)
    .ToListAsync();

RequestParameters模型

public class RequestParameters
{
    const int MaxPageSize = 50;
    public int PageNumber { get; set; } = 1;
    private int _pageSize = 25;
    private string _filterDescString = "";
    private string _filterAunumberString = "";
    private int? _filterItemIdInt = null;
    private int? _filterAmountInt = null;
    private int? _filterWidthInt = null;
    private int? _filterHeightInt = null;
    private int? _filterWeightInt = null;

    public int PageSize
    {
        get
        {
            return _pageSize;
        }
        set
        {
            _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
        }
    }

    public string FilterDescString
    {
        get
        {
            return _filterDescString;
        }
        set
        {
            _filterDescString = (value != null) ? value : _filterDescString;
        }
    }

    public string FilterAunumberString
    {
        get
        {
            return _filterAunumberString;
        }
        set
        {
            _filterAunumberString = (value != null) ? value : _filterAunumberString;
        }
    }

    public int? FilterItemIdInt
    {
        get
        {
            return _filterItemIdInt;
        }
        set
        {
            _filterItemIdInt = (value != null) ? value : _filterItemIdInt;
        }
    }

    public int? FilterAmountInt
    {
        get
        {
            return _filterAmountInt;
        }
        set
        {
            _filterAmountInt = (value != null) ? value : _filterAmountInt;
        }
    }

    public int? FilterWidthInt
    {
        get
        {
            return _filterWidthInt;
        }
        set
        {
            _filterWidthInt = (value != null) ? value : _filterWidthInt;
        }
    }

    public int? FilterHeightInt
    {
        get
        {
            return _filterHeightInt;
        }
        set
        {
            _filterHeightInt = (value != null) ? value : _filterHeightInt;
        }
    }

    public int? FilterWeightInt
    {
        get
        {
            return _filterWeightInt;
        }
        set
        {
            _filterWeightInt = (value != null) ? value : _filterWeightInt;
        }
    }
}

当前问题

当调用接口时传入空值INT参数(比如初始调用):

https://localhost:7010/api/Items?PageNumber=0&PageSize=25&FilterDescString=&FilterAunumberString=&FilterAmountInt=null&FilterWidthInt=null&FilterHeightInt=null&FilterWeightInt=null&FilterItemIdInt=null

此时会返回空数组,因为原逻辑强制要求所有INT参数匹配null值,但数据库中没有对应字段为null的数据。


解决方案

方案1:直接修改查询表达式

针对每个可空INT参数,添加「参数为null则跳过该条件」的逻辑,修改后的查询函数如下:

public async Task<List<Item>> GetAsync(RequestParameters requestParameters) =>
    await _itemsCollection.Find(item => 
        // 字符串过滤逻辑保持不变
        (item.item_description.Contains(requestParameters.FilterDescString) || item.item_adddesc.Contains(requestParameters.FilterDescString)) &&
        // INT参数为空则忽略,否则匹配对应字段
        (requestParameters.FilterItemIdInt == null || item.item_id.Equals(requestParameters.FilterItemIdInt)) &&
        (requestParameters.FilterAmountInt == null || item.item_amount.Equals(requestParameters.FilterAmountInt)) &&
        (requestParameters.FilterWidthInt == null || item.item_width.Equals(requestParameters.FilterWidthInt)) &&
        (requestParameters.FilterHeightInt == null || item.item_height.Equals(requestParameters.FilterHeightInt)) &&
        (requestParameters.FilterWeightInt == null || item.item_weight.Equals(requestParameters.FilterWeightInt)) &&
        item.item_aunumber.Contains(requestParameters.FilterAunumberString)
    )
    .SortByDescending(i => i.item_id)
    .Skip(requestParameters.PageNumber * requestParameters.PageSize)
    .Limit(requestParameters.PageSize)
    .ToListAsync();

逻辑说明

  • 对于每个可空INT参数,判断逻辑改为:参数为null 或者 字段值等于参数值
  • 当参数为null时,表达式直接返回true,相当于跳过该过滤条件
  • 当参数有值时,执行原本的字段匹配逻辑

方案2:使用FilterBuilder动态拼接条件(推荐)

如果后续过滤条件较多,推荐用MongoDB的FilterDefinitionBuilder动态拼接过滤条件,代码可读性和可维护性更强:

public async Task<List<Item>> GetAsync(RequestParameters requestParameters)
{
    var filterBuilder = Builders<Item>.Filter;
    var filter = filterBuilder.Empty;

    // 添加字符串过滤条件
    var descFilter = filterBuilder.Or(
        filterBuilder.Where(item => item.item_description.Contains(requestParameters.FilterDescString)),
        filterBuilder.Where(item => item.item_adddesc.Contains(requestParameters.FilterDescString))
    );
    filter &= descFilter;

    var aunumberFilter = filterBuilder.Where(item => item.item_aunumber.Contains(requestParameters.FilterAunumberString));
    filter &= aunumberFilter;

    // 动态添加INT过滤条件
    if (requestParameters.FilterItemIdInt.HasValue)
    {
        filter &= filterBuilder.Where(item => item.item_id.Equals(requestParameters.FilterItemIdInt.Value));
    }

    if (requestParameters.FilterAmountInt.HasValue)
    {
        filter &= filterBuilder.Where(item => item.item_amount.Equals(requestParameters.FilterAmountInt.Value));
    }

    if (requestParameters.FilterWidthInt.HasValue)
    {
        filter &= filterBuilder.Where(item => item.item_width.Equals(requestParameters.FilterWidthInt.Value));
    }

    if (requestParameters.FilterHeightInt.HasValue)
    {
        filter &= filterBuilder.Where(item => item.item_height.Equals(requestParameters.FilterHeightInt.Value));
    }

    if (requestParameters.FilterWeightInt.HasValue)
    {
        filter &= filterBuilder.Where(item => item.item_weight.Equals(requestParameters.FilterWeightInt.Value));
    }

    return await _itemsCollection.Find(filter)
        .SortByDescending(i => i.item_id)
        .Skip(requestParameters.PageNumber * requestParameters.PageSize)
        .Limit(requestParameters.PageSize)
        .ToListAsync();
}

优势

  • 逻辑拆分清晰,每个过滤条件单独处理
  • 避免长表达式嵌套,可读性更强
  • 方便后续扩展更多过滤条件

内容的提问来源于stack exchange,提问作者meDom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:15:13