EF 4 在 SQL 中生成 UNICODE 字符串常量,其中列类型为 varchar。如何避免?

发布于 2024-11-03 17:23:41 字数 941 浏览 1 评论 0原文

在我的代码中,我有以下 L2E 查询片段:

where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN") && ol.olstatus == "9"

这将转换为以下 SQL 片段:

WHERE ([Extent8].[ohcustno] = @p__linq__1) AND (''IN'' = [Extent7].[ollastdoctype]) AND (''9'' = [Extent7].[olstatus]) ...

对于某个输入,查询执行 3 秒。我以这种方式更改查询:

where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN" || ol.ollastdoctype == "CR") && ol.olstatus == "9"

生成的 SQL 更改如下:

WHERE ([Extent6].[ohcustno] = @p__linq__1) AND ([Extent5].[ollastdoctype] IN (N''IN'',N''CR'')) AND (''9'' = [Extent5].[olstatus]) ...

请注意,由于某些奇怪的原因,实体框架决定将我的 IN 和 CR 转换为 unicode。结果是查询现在对同一输入执行 6 秒。如果我手动从 IN 子句中删除 N 前缀并在 SSMS 中重新运行查询,则执行时间将恢复到 3 秒。这当然是因为 SQL Server 查询优化器无法利用索引,因为比较的类型现在不同(varchar 与 nvarchar)

谁能解释一下为什么实体框架突然决定将我的常量转换为 unicode,我该如何避免它吗?

In my code I have the following fragment of a L2E query:

where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN") && ol.olstatus == "9"

This translates to following SQL fragment:

WHERE ([Extent8].[ohcustno] = @p__linq__1) AND (''IN'' = [Extent7].[ollastdoctype]) AND (''9'' = [Extent7].[olstatus]) ...

On a certain input the query executes 3 seconds. I change the query this way:

where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN" || ol.ollastdoctype == "CR") && ol.olstatus == "9"

and the resulting SQL changes are as follows:

WHERE ([Extent6].[ohcustno] = @p__linq__1) AND ([Extent5].[ollastdoctype] IN (N''IN'',N''CR'')) AND (''9'' = [Extent5].[olstatus]) ...

Note, that for some bizarre reason Entity Framework decided to convert my IN and CR to unicode. The result is that the query now executes 6 seconds on the same input. If I manually remove the N prefix from the IN clause and re-run query in SSMS the execution time goes back to 3 seconds. This is of course because SQL Server Query Optimizer can't get advantage of an index because compared types are now different (varchar vs nvarchar)

Can anyone explain me why Entity Framework all of a sudden decides to convert my constants to unicode and how can I avoid it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半城柳色半声笛 2024-11-10 17:23:41

您可以尝试此方法 EntityFunction.AsNonUnicode,如下

where ol.ordhead.ohcustno == login && 
   (ol.ollastdoctype == EntityFunctions.AsNonUnicode("IN") || 
   ol.ollastdoctype == EntityFunctions.AsNonUnicode("CR")) && 
   ol.olstatus == "9"

这只是最后的希望,下一步是将 bug 报告给微软。

you can try this method EntityFunction.AsNonUnicode, as follow

where ol.ordhead.ohcustno == login && 
   (ol.ollastdoctype == EntityFunctions.AsNonUnicode("IN") || 
   ol.ollastdoctype == EntityFunctions.AsNonUnicode("CR")) && 
   ol.olstatus == "9"

This is only last hope, next is report bug to microsoft.

一杯敬自由 2024-11-10 17:23:41

EntityFunction.AsNonUnicode 解决方法实际上非常有限,它仅在提供的值是文字或字符串时才有效:

System.NotSupportedException:方法“System.String”
AsNonUnicode(System.String)' 仅在 LINQ to Entities 中受支持
当参数是字符串变量或文字时。

这是 EF4.1 中的一个严重问题,也已记录在此处:
http://connect.microsoft.com/VisualStudio/feedback/details/650410/entity-framework-contains-still-defaulting-to-unicode-for-varchar-fields

直到这是EF 本身已修复,除了拦截查询并使用 EFTraceProvider 等手动替换语法之外,没有其他解决方法。

野蛮。

The EntityFunction.AsNonUnicode workaround is actually quite limited, it only works when the value supplied is either a literal or a string:

System.NotSupportedException: The method 'System.String
AsNonUnicode(System.String)' is only supported in LINQ to Entities
when the argument is a string variable or literal.

This is a serious problem in EF4.1 and has been documented here as well:
http://connect.microsoft.com/VisualStudio/feedback/details/650410/entity-framework-contains-still-defaulting-to-unicode-for-varchar-fields

Until this is fixed in EF itself, there is no workaround short of intercepting the query and manually replacing the syntax using something like EFTraceProvider.

Brutal.

葬シ愛 2024-11-10 17:23:41

该问题已在最新的 EF 版本中得到正式解决。您可以使用 DataAnnotations 定义列类型。希望这对某人有帮助!

请参阅此答案:EF 数据注释列类型

This issue has been officially resolved in the latest EF versions. You can define the column type using DataAnnotations. Hope this helps someone!

See this answer: EF Data Annotations Column Type

对你而言 2024-11-10 17:23:41

在 ODP.net Beta 2 发布之前这是一个问题,但随着 ODP.net 4.112.2.50 Beta3 版本的发布,这个问题得到了解决。

This was a problem till ODP.net Beta 2 release but with Beta3 release of ODP.net 4.112.2.50 this problem is solved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文