LINQ to Entities仅支持无参数构造函数和初始器报错如何解决
错误原因
报错Only parameterless constructors and initializers are supported in LINQ to Entities的核心原因是:EF的LINQ to Entities需要将查询表达式翻译为SQL语句执行,无法直接识别并转换自定义类的带参数构造函数调用。你代码里new ParameterlessTuple<...>(conf, yes, no, cancel)用了带4个参数的构造方法,触发了这个限制。
你之前添加.ToList()无效,是因为你把调用放在了整个查询末尾,LINQ to Entities依然会先尝试把整个表达式翻译为SQL,带参构造的部分仍然无法被识别。
解决方法
方案1(优先选择,性能更好)
如果需要保持属性返回IQueryable类型,且后续还要基于这个查询拼接数据库过滤条件,给ParameterlessTuple添加无参构造函数,然后改用对象初始化器赋值即可。假设ParameterlessTuple的四个属性对应为Item1/Item2/Item3/Item4,修改后的select部分如下:
select new ParameterlessTuple<tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration> { Item1 = conf, Item2 = yes, Item3 = no, Item4 = cancel }
方案2(适用于查询后不需要额外拼接数据库过滤的场景)
先把匹配的数据库数据加载到内存,再执行Tuple构造,修改完整代码如下:
internal IQueryable<ParameterlessTuple<tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration>> DataCollectionAcessQuery { get => (from conf in (from conf in this.Scope.Set<tcDataCollectionConfiguration>() where conf.DCC_ParameterName == "conf" select conf) join yes in (from yes in this.Scope.Set<tcDataCollectionConfiguration>() where yes.DCC_ParameterName == "YesCode" select yes) on conf.DCC_StationID equals yes.DCC_StationID join no in (from no in this.Scope.Set<tcDataCollectionConfiguration>() where no.DCC_ParameterName == "NoCode" select no) on conf.DCC_StationID equals no.DCC_StationID join cancel in (from cancel in this.Scope.Set<tcDataCollectionConfiguration>() where cancel.DCC_ParameterName == "cancel" select cancel) on conf.DCC_StationID equals cancel.DCC_StationID // 先将查询到的实体映射为匿名类型加载到内存,后续操作转为LINQ to Objects,不受EF转SQL的语法限制 select new { conf, yes, no, cancel }).AsEnumerable() .Select(x => new ParameterlessTuple<tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration, tcDataCollectionConfiguration>(x.conf, x.yes, x.no, x.cancel)) .AsQueryable(); }
注意:该方案后续对
DataCollectionAcessQuery追加的过滤、排序等操作都会在内存执行,不会转成SQL到数据库侧执行,数据量较大时会有性能损耗。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

