简体   繁体   English

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

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

I have a query against a SQL server database that throws an Error converting data type nvarchar to numeric. 我有一个针对SQL Server数据库的查询,该查询引发Error converting data type nvarchar to numeric. exception. 例外。 I was trying to use Convert.ToDecimal on a varchar field, however I'll eyeballed the data as best I could and couldn't find an invalid value. 我试图在varchar字段上使用Convert.ToDecimal ,但是我将尽我所能地盯着数据,并且也找不到无效的值。

The query is filtering the table by a 'Group' by using the foreign key of p.pgKey=# . 该查询正在使用p.pgKey=#的外键按“组”过滤表。 However, if I use the navigation property and filter by the navigation property instead, p.Group.gName='ABC' the query works. 但是,如果我使用导航属性并改为按导航属性过滤,则p.Group.gName='ABC'可以运行查询。

Here are the queries (note, originally, I didn't know if error was happening in Where translation or the Select processing, so that is why query looks weird, but as you can guess, when it works, it should just return a single distinct row of true ): 这是查询(请注意,最初,我不知道在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();

The above query fails, while this query succeeds: 以上查询失败,而该查询成功:

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();

Below is a full LINQPad screen dump showing: 下面是完整的LINQPad屏幕转储,显示:

  1. Proves the gKey for ABC is 237. 证明ABC的gKey为237。
  2. Proves that the counts of simplying counting the Profile records is identical when using pgKey or Group.gName . 证明使用pgKeyGroup.gName时, pgKey统计Profile记录的计数是相同的。
  3. Shows the query working correctly when using the Group.gName processing. 显示使用Group.gName处理时查询正常工作。
  4. Shows the query failing when using the pgKey processing. 使用pgKey处理时显示查询失败。

LINQPad屏幕截图

Obviously I've used the Group.gName method to fix my problem, but I stumbled on that solution by accident. 显然,我已经使用Group.gName方法解决了我的问题,但是偶然发现了该解决方案。 Anyone know why LINQ to SQL would behave this way? 有人知道为什么LINQ to SQL会这样吗?

Note : I get the same behavior using the generated DataContext from LINQPad or if I run against a compiled .dbml DataContext. 注意 :使用LINQPad生成的DataContext或针对编译的.dbml DataContext运行时,我会得到相同的行为。

The two queries will be generating different TSQL and hence the query plan will be different. 这两个查询将生成不同的TSQL,因此查询计划将不同。

I would suspect that the former query is attempting to convert some values of pSearch08 to decimal before it rejects them based on the other selection criteria, whereas the latter query is performing the other selection criteria first and hence is attempting to convert a smaller number of pSearch08 values to decimal and hence does not attempt to convert the invalid value. 我怀疑前一个查询试图将pSearch08的某些值转换为十进制, 然后才根据其他选择条件拒绝它们,而后一个查询首先执行其他选择条件,因此尝试转换较少的pSearch08值转换为十进制,因此不会尝试转换无效值。

If this is the case, then it could be dangerous to assume that the second query will always work and it would be best to fix the invalid data. 如果是这种情况,那么假设第二个查询将始终有效,则最好进行修复,以修复无效数据。

Rather than eyeballing the data you can try 不必盯着数据,您可以尝试

SELECT * from Profile where ISNUMERIC(pSearch08) = 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM