Nic*_*ick 5 c# odp.net entity-framework-6
我当前使用Oracle托管驱动程序(v12.1.2400)作为我的Entity Framework驱动程序,并且当前ORA-12704: character set mismatch在执行过程中看到错误。
我正在使用的LINQ-> SQL代码如下:
from c in CUSTOMER.AsNoTracking()
where c.ACCOUNT.Contains("DE")
&& c.DELETED == "N"
orderby (c.FORENAME + c.SURNAME)
select new { c.ACCOUNT, c.FORENAME, c.SURNAME})
Run Code Online (Sandbox Code Playgroud)
这将创建以下SQL:
SELECT "Project1"."C2" AS "C1",
"Project1"."ACCOUNT" AS "ACCOUNT",
"Project1"."FORENAME" AS "FORENAME",
"Project1"."SURNAME" AS "SURNAME"
FROM (
SELECT( (CASE WHEN ("Extent1"."FORENAME" IS NULL) THEN N''
ELSE "Extent1"."FORENAME" END)
||(CASE WHEN ("Extent1"."SURNAME" IS NULL) THEN N''
ELSE "Extent1"."SURNAME" END)) AS "C1",
"Extent1"."ACCOUNT" AS "ACCOUNT",
"Extent1"."FORENAME" AS "FORENAME",
"Extent1"."SURNAME" AS "SURNAME",
1 AS "C2"
FROM "TEST"."CUSTOMER" "Extent1"
WHERE (("Extent1"."ACCOUNT" LIKE '%DE%')
AND ('N' = "Extent1"."DELETED"))) "Project1"
ORDER BY "Project1"."C1" ASC;
Run Code Online (Sandbox Code Playgroud)
当我调试SQL,我可以看到的问题是,SQL正在使用N''的CASE部分。AS列不是unicode,如果我删除前面的内容N,''则sql可以正常工作。
有什么办法可以防止这种默认设置?
当前所有的数据库列均已VARCHAR使用C#建模string。
两列的代码优先映射如下:
this.Property(t => t.FORENAME).HasColumnName("FORENAME").IsUnicode(false).HasMaxLength(35);
this.Property(t => t.SURNAME).HasColumnName("SURNAME").IsUnicode(false).HasMaxLength(35);
Run Code Online (Sandbox Code Playgroud)
我期望IsUnicode(false)声明能够解决这个问题。
仅供参考,这在我使用EF5和非托管驱动程序时可以正常工作。
此外,Devart dotConnectForOracle驱动程序不存在此问题,因此我认为这是Oracle驱动程序中的错误。
我从未找到正确的解决方案,但我确实找到了一种效果很好的解决方法。
我创建了一个NVarcharInterceptor实现 的拦截器类IDbCommandInterceptor,并重写了所有方法..Executing(..)以包含以下代码:
if (command != null && !string.IsNullOrWhiteSpace(command.CommandText))
command.CommandText = command.CommandText.Replace("N''", "''");
Run Code Online (Sandbox Code Playgroud)
这有效地NVarchar从我的DbContext.
为了添加拦截器,我按类添加了以下代码DBConfiguration:
this.AddInterceptor(new NVarcharInterceptor());
Run Code Online (Sandbox Code Playgroud)