Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c# - ODP.Net Managed Driver - ORA-12704: character set mismatch in generated code

I am currently using the Oracle Managed Driver (v12.1.2400) as my Entity Framework driver, and am currently seeing a ORA-12704: character set mismatch error during execution.

The LINQ->SQL code I am using is as follows:

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})

and this is creating the following 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;

When I debug that SQL, I can see the issue is that the SQL is using N'' in the CASE sections. AS teh columns are not unicode, if I remove the preceding N to leave just '' then the sql works as expected.

Is there any way I can prevent this defaulting?

All db columns are currently VARCHAR, and are modeled in C# as string.
Code first mappings for the two columns are as follows:

this.Property(t => t.FORENAME).HasColumnName("FORENAME").IsUnicode(false).HasMaxLength(35);
this.Property(t => t.SURNAME).HasColumnName("SURNAME").IsUnicode(false).HasMaxLength(35);

I was expecting that the IsUnicode(false) statement would take care of this.

FYI, this used to work when I used EF5 and the non-managed driver.
In addition, the Devart dotConnectForOracle drivers dont have this issue, so I am thinking this is a bug in the Oracle drivers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I never did find the proper solution to this, however I did find a workaround that works well.

I created an Interceptor class NVarcharInterceptor implementing IDbCommandInterceptor, and overrode all of the ..Executing(..) methods to contain the following code:

if (command != null && !string.IsNullOrWhiteSpace(command.CommandText))
    command.CommandText = command.CommandText.Replace("N''", "''");   

This effectively removes any of the unwanted NVarchar references, from any command being executed on my DbContext.

To add the interceptor, I added the following code to by DBConfiguration class:

this.AddInterceptor(new NVarcharInterceptor());

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...