You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF6 SQL Server查询使用Contains时异常问题排查

问题描述

我有一个EF6 SQL Server查询,在传入List<int>类型的ID列表时表现异常:

  • 当bookGenieCategory为有效值时查询正常;
  • 当selectedAges为空(count=0)时查询正常;
  • 但当selectedAges包含ProductCategory.CategoryId列中存在的值时,Contains查询失效,无任何行返回。

注:AllocationCandidates是一个独立使用正常的视图,其定义如下:

CREATE VIEW dbo.AllocationCandidate
AS
    SELECT         
        p.ProductID, p.SKU as ISBN, p.Name as Title, 
        pv.MSRP, pv.Price, pv.VariantID, pv.Inventory, 
        ISNULL(plt.DateLastTouched, GETDATE()) AS DateLastTouched, 
        JSON_VALUE(p.MiscText, '$.AgeId') AS AgeId, 
        JSON_VALUE(p.MiscText, '$.AgeName') AS AgeName
    FROM            
        dbo.Product AS p WITH (NOLOCK) 
    INNER JOIN
        dbo.ProductVariant AS pv WITH (NOLOCK) ON pv.ProductID = p.ProductID 
    LEFT OUTER JOIN
        dbo.KBOProductLastTouched AS plt WITH (NOLOCK) ON plt.ProductID = p.ProductID
    WHERE        
        (ISJSON(p.MiscText) = 1) 
        AND (p.Deleted = 0) 
        AND (p.Published = 1) 
        AND (pv.IsDefault = 1)
GO

请问以下EF查询代码是否存在拼写错误或括号误用?

var returnList = (from ac in _db.AllocationCandidates
                  join pc in _db.ProductCategories on ac.ProductID equals pc.ProductID
                  where (bookGenieCategory == 0
                         || bookGenieCategory == pc.CategoryID)
                    &&
                    (selectedAges.Count == 0 ||
                     selectedAges.Contains(pc.CategoryID))
                  orderby ac.AgeId, ac.DateLastTouched descending
                  select ac).ToList();
问题排查与解决

这段EF代码存在字段误用的问题,并非括号或拼写错误:

在selectedAges.Contains(pc.CategoryID)这一行,错误地用了pc.CategoryID(产品分类ID)来匹配selectedAges(年龄ID列表)。根据视图定义,年龄ID存储在ac.AgeId字段中,而pc.CategoryID是产品所属分类的ID,两者属于完全不同的业务维度,自然无法匹配,导致查询无结果。

为什么其他场景能正常工作?

  • 当bookGenieCategory为有效值时:此时查询只受分类条件过滤,年龄条件因selectedAges.Count==0不生效,所以结果正常;
  • 当selectedAges为空时:年龄条件直接跳过,只执行分类过滤,结果正常;
  • 只有当selectedAges有值时,错误的字段匹配导致没有符合pc.CategoryID in selectedAges的行,所以返回空。

修正后的代码

var returnList = (from ac in _db.AllocationCandidates
                  join pc in _db.ProductCategories on ac.ProductID equals pc.ProductID
                  where (bookGenieCategory == 0
                         || bookGenieCategory == pc.CategoryID)
                    &&
                    (selectedAges.Count == 0 ||
                     selectedAges.Contains(ac.AgeId)) // 这里改为ac.AgeId
                  orderby ac.AgeId, ac.DateLastTouched descending
                  select ac).ToList();

内容的提问来源于stack exchange,提问作者BedfordNYGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:56:02