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

LINQ to SQL query succeeds or fails based on using foreign key versus using a built in navigation property

我有一个针对 SQL 服务器数据库的查询,该数据库抛出 Error converting data type nvarchar to numeric. 异常。我试图在 varchar 字段上使用 Convert.ToDecimal,但是我会尽我所能 目测 数据,但找不到无效值。

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

这是查询(注意,最初,我不知道 Where 翻译或 Select 处理是否发生错误,所以这就是查询看起来很奇怪的原因,但正如你可以猜到,当它工作时,它应该只是 return 一个不同的行 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 屏幕转储显示:

  1. 证明 ABC 的 gKey 是 237。
  2. 证明使用pgKeyGroup.gName.
  3. 时,简单计算Profile记录的计数是相同的
  4. 显示使用 Group.gName 处理时查询工作正常。
  5. 显示使用 pgKey 处理时查询失败。

显然我已经使用 Group.gName 方法解决了我的问题,但我偶然发现了那个解决方案。有人知道为什么 LINQ to SQL 会这样吗?

注意:我使用从 LINQPad 生成的 DataContext 得到相同的行为,或者如果我 运行 针对已编译的 .dbml DataContext。

这两个查询将生成不同的 TSQL,因此查询计划也会不同。

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

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

与其盯着数据,不如试试

SELECT * from Profile where ISNUMERIC(pSearch08) = 0