Closed ElAdriano closed 1 month ago
@ElAdriano Thanks for reporting this error and your thorough analysis. I've been able to reproduce the error as well and have created a bug (36179160) to have the ODP.NET dev team review and resolve the problem.
@ElAdriano After further investigation, the problem in the console sample program is that the encoding was not set to UTF8. If you add the following line to the sample program prior to retrieving the results, you will see the correct data returned.
Console.OutputEncoding = Encoding.UTF8;
This works for both the test cases that use
var result = db.B1TestRepo.Where(e => e.Mynchar == "ęłćń").FirstOrDefault();
and
var result = db.B1TestRepo.Where(e => e.Mynchar == mynchar).FirstOrDefault();
Does this problem still reproduce for you with another method of retrieval?
@alexkeh Yes, it still occurs. Encoding for console wasn't set, but I think that's just logging stuff. When it comes to fetching the data from db, results are still the same.
// this returns null
var result = db.B1TestRepo.Where(e => e.Mynchar == "ęłćń").FirstOrDefault();
// this works fine
string mynchar = "ęłćń";
var otherResult = db.B1TestRepo.Where(e => e.Mynchar == mynchar).FirstOrDefault();
@ElAdriano If I put a watch on on the result
, I see it returning "ęłćń" in the code you see null getting returned. I had a colleague test this with his own instance. He also got the returned the valid results.
Do you see this issue also occur with EF Core 7?
What SQL do you see executed in log trace?
@alexkeh It occurs for EF Core 7 as well. In log trace I see that proper query has been sent
Executed query:
SELECT "b"."MYNCHAR"
FROM "B1TEST" "b"
WHERE "b"."MYNCHAR" = N'ęłćń'
FETCH FIRST 1 ROWS ONLY
but unfortunately it still returns null for that one specific case:
@ElAdriano Perhaps the reason for the data mismatch is the DB configuration then. What are your DB's NLS_CHARACTERSET and NLS_NCHAR_CHARACTERSET parameter values?
@alexkeh I see in debugger that NLS configuration for the connection looks like this: but the bug still occurs, even after changing to proper language and territory:
Also I think that saving entity to db wouldn't work if it was caused by improper NLS settings.
@ElAdriano I don't see the NLS_CHARACTERSET nor NLS_NCHAR_CHARACTERSET values. Can you run the following queries in your DB to return that info?
select value from nls_database_parameters where parameter='NLS_NCHAR_CHARACTERSET'
select value from nls_database_parameters where parameter='NLS_CHARACTERSET'
I see that those parameters are set as: NLS_NCHAR_CHARACTERSET = "AL16UTF16" NLS_CHARACTERSET = "WE8ISO8859P15"
Base bug is 35982927.
@ElAdriano @alexkeh
In my case, I encountered a similar issue with MySQL using Vietnamese characters with diacritics, similar to your case with 'ęłćń' in Oracle.
Adding charset=utf8mb4
to the ConnectionString resolved the issue, allowing MySQL to handle the characters correctly.
I hope this will be helpful to you.
Environment:
After some more investigation by the Oracle NLS team, they've concluded that this issue is fundamentally an enhancement request, rather than a bug. ODP.NET would need to implement an NCHAR literal replacement feature.
With that said, this missing feature likely affects a small number of apps and has a simple workaround. If implemented for EF Core, it could have negative performance implications for many apps. Oracle EF Core would need to add U literal or UNISTR function whenever a string literal is used, rather than under specific Unicode conditions. That's a performance cost for every Oracle EF Core app that isn't affected by this issue.
Thus, the Oracle EF Core team has decided not to add this functionality for now. If we see more votes for this enhancement and reasons why the workaround can't be used, we can reconsider.
The existing workaround is to use a parameterized value for the string comparison instead of string literal in the LINQ. That is not hard to implement and a better query practice. Parameterized queries protect against query injection, improve performance, and enhance maintainability.
In EF Core 9, a new feature, EF.Parameter
, has been introduced that forces EF to use a parameter even if the value is a literal. For example:
async Task<List<Post>> GetPostsForceParameter(int id)
=> await context.Posts
.Where(
e => e.Title == EF.Parameter(".NET Blog") && e.Id == id)
.ToListAsync();
The SQL translation now contains a parameter for the ".NET Blog" string:
SELECT [p].[Id], [p].[Archived], [p].[AuthorId], [p].[BlogId], [p].[Content], [p].[Discriminator], [p].[PublishedOn], [p].[Title], [p].[PromoText], [p].[Metadata]
FROM [Posts] AS [p]
WHERE [p].[Title] = @__p_0 AND [p].[Id] = @__id_1
When Oracle EF Core supports EF Core 9, this will be an option to use string literals in LINQ.
Problem: In latest version of Oracle.EntityFrameworkCore lib can't query data from db when special characters are explicitly used in sent query.
Environment: Lib version : 8.21.121 .NET SDK version : 8.0.100 Database : Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production Version 19.3.0.0.0 (I'm connecting to existing one and don't run CreateDatabase)
Description: When use following code
I receive NullReferenceException because of null result returned by .Where clause - despite the fact that in database there was created record with Mynchar = "ęłćń" (shown below).
In logs, the following query (with corrupted special characters) was sent to db:
However there were also 2 things worth attention:
Steps to recreate
Table DDL (create table in database):
Full C# code (Program.cs):
csproj: