为何在函数中给IQueryable<T>添加Where子句需使用ref关键字?
为什么IQueryable的Where子句在AddWhereToQuery中不生效?
核心原因:C#参数传递规则 + IQueryable的不可变性
- C#默认按值传递参数:哪怕是引用类型,传递给方法的是引用的副本。你在
AddWhereToQuery里给queryable赋值新实例,只是修改了这个副本的指向,和外部的原变量完全没关系。 - IQueryable的Where方法不修改原实例:
Where不会在原IQueryable对象上追加过滤条件,而是返回一个全新的IQueryable实例——这个新实例包含了原查询逻辑加上Where过滤规则。
看你的代码示例1:
- 外部的
queryable指向_db.Articles.AsQueryable()生成的实例 - 调用
AddWhereToQuery(queryable)时,方法内部的queryable是原引用的副本 - 方法内执行
queryable = queryable.Where(...),只是让这个副本指向了新的实例,但外部的原变量仍指向最初的实例,所以ToQueryString()看不到Where条件
为什么加ref就生效?
ref关键字让参数变成按引用传递,此时方法里的queryable直接关联外部的原变量。当你给它赋值新的IQueryable实例时,外部的变量也会同步指向这个新实例,自然就能看到Where条件了。
更推荐的写法(无需使用ref)
其实没必要用ref,让方法直接返回新的IQueryable实例更符合C#编码习惯:
[HttpGet] public IActionResult Get() { var queryable = _db.Articles.AsQueryable(); queryable = AddWhereToQuery(queryable); // 接收返回的新实例 var queryString = queryable.ToQueryString(); return Ok(queryString); } private IQueryable<Article> AddWhereToQuery(IQueryable<Article> queryable) { return queryable.Where(x => x.Status == ArticleStatus.Active); }
内容的提问来源于stack exchange,提问作者Hromis
相关产品推荐
相关产品推荐

