Entity Framework Core封装查询返回DTO后调用Where过滤报错如何解决
问题原因
LINQ的Where扩展方法仅支持实现了IEnumerable<T>或IQueryable<T>接口的类型调用,你当前调用Where的对象是自定义的AllPractitionerLocationsDTO类,该类本身没有实现上述接口,仅在内部持有一个List<AllPractitionerLocationDTO>类型的MyList属性,因此会抛出找不到Where方法的错误,和DTO字段是否匹配表结构没有关系。
你之前直接查询数据库时pracloc的类型是EF返回的IQueryable<AllPractitionerLocation>,天然支持LINQ方法,所以可以正常运行。另外你加DbSet<AllPractitionerLocationDTO>的操作完全不需要,DTO是内存传输对象,不需要映射到数据库表,该配置没有作用。
还有两个隐藏的语法/结构问题需要先修复:
- 你当前的过滤条件用了单等号
=,这是赋值操作,不是等值判断,需要改成双等号== AllPractitionerLocationDTO中没有定义LocationID字段,需要先补充该字段才能正常按LocationID过滤
解决方案
方案1:直接访问内部集合(最简便)
过滤时直接调用DTO内部的MyList属性,List<T>本身实现了IEnumerable<T>,支持所有LINQ操作:
// 直接对MyList执行过滤 var PracLocation = pracloc.MyList .FirstOrDefault(a => a.LocationID == provider.LocationID);
无需修改原有DTO和封装方法的代码。
方案2:让DTO支持直接LINQ调用
如果希望AllPractitionerLocationsDTO可以直接调用LINQ方法,不需要每次访问MyList,可以让DTO实现IEnumerable<AllPractitionerLocationDTO>接口:
using System.Collections; using System.Collections.Generic; public class AllPractitionerLocationsDTO : IEnumerable<AllPractitionerLocationDTO> { public List<AllPractitionerLocationDTO> MyList = new(); public IEnumerator<AllPractitionerLocationDTO> GetEnumerator() { return MyList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
修改完成后,原有过滤代码仅需修正等号即可正常运行:
var PracLocation = pracloc .FirstOrDefault(a => a.LocationID == provider.LocationID);
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

