Sto testando Entity Framework 6.2 con un database Oracle, ma ho riscontrato problemi durante il tentativo di partecipare a più condizioni con la conversione.
Devo abbinare TABLE2_ID (NUMBER)
con TABLE2.ID (VARCHAR2)
che sono diversi tipi di valore. Il problema è che il metodo ToString()
traduce in TO_NCLOB
invece di TO_NCHAR
che funzionerebbe.
var query = from table1 in context.TABLE1
join table2 in context.TABLE2 on table1.TABLE2_ID.ToString() equals table2.ID
select new
{
table1.NAME,
table2.TEXT
};
L'SQL generato sembra il seguente:
SELECT
1 AS "C1",
"Extent1"."NAME" AS "NAME",
"Extent2"."TEXT" AS "TEXT"
FROM "USER"."TABLE1" "Extent1"
INNER JOIN "USER"."TABLE2" "Extent2" ON
(CASE WHEN ("Extent1"."TABLE2_ID" IS NULL) THEN N''
// At this point I need TO_NCHAR
ELSE TO_NCLOB("Extent1"."TABLE2_ID") END) = "Extent2"."ID"
Questo risulta in:
ORA-00932: tipi di dati incoerenti: NCHAR previsto ha ottenuto NCLOB
So che ci sono molte domande con quasi la stessa eccezione ma solo con casi d'uso diversi, quindi per favore guarda come posso risolvere questo problema.
Ad esempio c'è un modo per sovrascrivere la traduzione SQL ToString()
?
PROBLEMA PRINCIPALE: LINQ to SQL .ToString()
converte in TO_NCLOB
ma ho bisogno di TO_NCHAR
o di un'altra soluzione.
Uso Visual Studio 2017 con Oracle Developer Tools per VS2017 12.2.0.11
Tristemente .ToString()
non è implementato così bene in Oracle Entity Framework. Quindi ho trovato una soluzione alternativa con questa risposta accettata per domande SO . L'installazione di EntityFramework.Functions
Nuget Package e l'utilizzo della TO_NCHAR
integrata TO_NCHAR
in Oracle hanno fatto il trucco nel modo seguente:
public static class OracleFunctions
{
[Function(FunctionType.BuiltInFunction, "TO_NCHAR")]
public static string ToNChar(this string value) => Function.CallNotSupported<string>();
}
Override di OnModelCreating in DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new FunctionConvention(typeof(OracleFunctions)));
}
E poi posso usarlo come questo che funziona in modo impeccabile:
var query = from table1 in context.TABLE1
join table2 in context.TABLE2 on table1.TABLE2_ID.ToNChar() equals table2.ID
select new
{
table1.NAME,
table2.TEXT
};