.NET 6中Where方法报错‘无接受2个参数的重载’,原代码在.NET Framework 4.6可用
问题描述
这段代码在.NET Framework 4.6里能正常运行,但迁移到.NET 6后编译器直接报错:
No overload for method 'Where' takes 2 arguments
我数据库里所有表都继承自ProgramObjects表,这个基表有个状态枚举列StatusEnumeration,值是Active(1)或者Inactive(2)——靠继承省了每张表加IsActive列的麻烦。写的泛型方法GetInactiveRecords<T>本来是要返回任意表的非活跃记录,原代码如下:
private IList<T> GetInactiveRecords<T>() { return ProgramObjects.OfType<T>() .Where("StatusEnumeration = @0", StatusEnum.Inactive) .ToList(); }
试过字符串插值也没用,求修复办法。
修复方案
你之前用的是EF(Entity Framework经典版,也就是EF6及更早版本)特有的Where重载——支持传字符串查询语句加参数,但.NET 6用的是EF Core,这个重载已经被移除了,得换写法:
方法一:用强类型Lambda表达式(推荐)
既然所有T类型都继承自ProgramObjects,先给泛型加个约束,然后直接用强类型的Lambda过滤就行,这也是EF Core推荐的类型安全写法:
private IList<T> GetInactiveRecords<T>() where T : ProgramObjects { return ProgramObjects.OfType<T>() .Where(obj => obj.StatusEnumeration == StatusEnum.Inactive) .ToList(); }
这种写法编译器还能帮你检查属性名对不对,不容易写错。
方法二:用EF Core原始SQL查询(特殊场景用)
如果确实必须用字符串形式的查询条件,可以用FromSqlRaw或者FromSqlInterpolated(注意防范SQL注入),不过要结合继承策略调整:
private IList<T> GetInactiveRecords<T>() where T : ProgramObjects { // 假设用的是EF Core默认的TPH继承策略,自动生成了Discriminator列区分子类 return ProgramObjects.FromSqlRaw( "SELECT * FROM ProgramObjects WHERE StatusEnumeration = {0} AND Discriminator = {1}", StatusEnum.Inactive, typeof(T).Name ) .OfType<T>() .ToList(); }
要是你用的是TPT(表每类型)继承策略,得把SQL语句改成关联对应子表的写法。
内容的提问来源于stack exchange,提问作者MLightsOut
相关产品推荐
相关产品推荐

