C# Linq链式Join关联查询添加Where子句报错如何解决
错误原因
该类型不匹配错误是因为_convRepository.AsQueryable()调用Where时,使用了IEnumerable<T>的扩展方法重载而非IQueryable<T>的重载,导致筛选后的集合类型从IQueryable<Conversation>降级为IEnumerable<Conversation>,而Join方法要求右侧关联集合为IQueryable类型,因此抛出参数类型错误。
常见触发场景是传入Where的是普通委托Func<Conversation,bool>而非表达式树Expression<Func<Conversation,bool>>,编译器会自动选择IEnumerable的Where重载。
正确实现方案
方案1:提前构造筛选后的会话IQueryable(推荐,关联前筛选性能更高)
// 全程保持IQueryable类型,避免降级 var filteredConversations = _convRepository.AsQueryable() .Where(c => !c.IsDeleted && c.DateCreated >= request.From && c.DateCreated <= request.To && c.HasRated); IQueryable<Rating> ratingsObj = _ratingRepository.AsQueryable() .Join( inner: filteredConversations, outerKeySelector: r => r.SessionId, innerKeySelector: c => c.CurrentConversationSid, resultSelector: (r, c) => new Rating() { Id = r.Id, SessionId = r.SessionId, Questions = r.Questions, AvgRatingValue = r.AvgRatingValue });
方案2:链式连写,强制保留IQueryable类型
IQueryable<Rating> ratingsObj = _ratingRepository.AsQueryable() .Join( _convRepository.AsQueryable() .Where(c => !c.IsDeleted && c.DateCreated >= request.From && c.DateCreated <= request.To && c.HasRated) .AsQueryable(), // 显式调用AsQueryable强制转回IQueryable类型 r => r.SessionId, c => c.CurrentConversationSid, (r, c) => new Rating() { Id = r.Id, SessionId = r.SessionId, Questions = r.Questions, AvgRatingValue = r.AvgRatingValue });
方案3:Join后统一筛选
IQueryable<Rating> ratingsObj = _ratingRepository.AsQueryable() .Join( _convRepository.AsQueryable(), r => r.SessionId, c => c.CurrentConversationSid, (r, c) => new { Rating = r, Conversation = c }) .Where(item => !item.Conversation.IsDeleted && item.Conversation.DateCreated >= request.From && item.Conversation.DateCreated <= request.To && item.Conversation.HasRated) .Select(item => new Rating() { Id = item.Rating.Id, SessionId = item.Rating.SessionId, Questions = item.Rating.Questions, AvgRatingValue = item.Rating.AvgRatingValue });
内容的提问来源于stack exchange,提问作者Ghazanfar Khan
相关产品推荐
相关产品推荐

