首页 文章

LINQ to SQL查询基于使用外键与使用内置导航属性成功或失败

提问于
浏览
1

我有一个SQL服务器数据库的查询,抛出 Error converting data type nvarchar to numeric. 异常 . 我试图在varchar字段上使用 Convert.ToDecimal ,但是我会尽可能地对数据进行处理,并且找不到无效值 .

该查询使用 p.pgKey=# 的外键通过'Group'过滤表 . 但是,如果我使用导航属性并通过导航属性进行过滤,则 p.Group.gName='ABC' 查询有效 .

以下是查询(注意,最初,我不知道是否在 Where 翻译或 Select 处理中发生了错误,所以这就是为什么查询看起来很奇怪,但正如你可以猜到的,当它工作时,它应该只返回一个 true )的不同行:

Profiles
    .Where(p =>
       p.pgKey == 237
       && !p.pPlanProfile.Value
      && Convert.ToDecimal(p.pSearch08 ?? "0") > 0
    ).Select(p =>
       Convert.ToDecimal(p.pSearch08 ?? "0") > 0
    )
    .Distinct()
    .Dump();

上述查询失败,而此查询成功:

Profiles
    .Where(p =>
       p.Groups.gName == "ABC"
       && !p.pPlanProfile.Value
       && Convert.ToDecimal(p.pSearch08 ?? "0") > 0
    ).Select(p =>
       Convert.ToDecimal(p.pSearch08 ?? "0") > 0
    )
    .Distinct()
    .Dump();

下面是一个完整的LINQPad屏幕转储显示:

  • 证明ABC的 gKey 是237 .

  • 使用 pgKeyGroup.gName 时,证明计算配置文件记录的简单计数是相同的 .

  • 使用 Group.gName 处理时显示查询正常工作 .

  • 使用 pgKey 处理时显示查询失败 .

LINQPad screenshot

显然我已经使用了 Group.gName 方法来解决我的问题,但我偶然发现了这个解决方案 . 任何人都知道为什么LINQ to SQL会以这种方式运行?

Note :我使用LINQPad生成的DataContext或者针对编译的.dbml DataContext运行时获得相同的行为 .

1 回答

  • 0

    这两个查询将生成不同的TSQL,因此查询计划将有所不同 .

    我怀疑前一个查询是试图将pSearch08的某些值转换为十进制 before 它根据其他选择标准拒绝它们,而后一个查询首先执行其他选择条件,因此试图转换较小数量的pSearch08值为十进制,因此不会尝试转换无效值 .

    如果是这种情况,那么假设第二个查询将始终有效并且最好修复无效数据可能是危险的 .

    您可以尝试,而不是眼睛看到数据

    SELECT * from Profile where ISNUMERIC(pSearch08) = 0
    

相关问题