Настройка Linq2Db для чтения и обновления с типом CHAR и ограничением NOT NULL в Oracle - PullRequest
0 голосов
/ 19 февраля 2020

Чтение значения фиксированной строки CHAR из таблицы с использованием поставщика Linq2db Oracle:

CREATE TABLE mytable
    (pk                         NUMBER(15,0) NOT NULL,
     fixed_data                 CHAR(20) DEFAULT ' ' NOT NULL)

Хотя в базе данных длина поля FIXED_DATA составляет 20,

SELECT LENGTH(fixed_data) FROM mytable WHERE pk = 1 

-- result is 20

Когда то же самое поле читается с использованием Linq2Db, значение усекается до пустой строки:

var row = (from row in database.mytable where row.pk == 1 select row).ToList()[0];
Console.WriteLine(row.fixed_data.Length);

// result is zero

Это вызывает проблему, когда запись обновляется с использованием Linq2Db, Oracle преобразует пустую строку в NULL, а при выполнении UPDATE происходит сбой:

database.Update(row);

// Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01407: cannot update ("MYSCHEMA"."MYTABLE"."FIXED_DATA") to NULL

Есть ли какие-либо настройки в Linq2Db для цикла чтения-> обновления для работы с типом CHAR и ограничением NOT NULL?

1 Ответ

1 голос
/ 19 февраля 2020

Нашел решение, благодаря общедоступному исходному коду. По умолчанию Linq2Db вызывает выражение IDataReader.GetString (int) .TrimEnd ('') для каждого столбца CHAR и NCHAR. Однако это можно легко настроить, внедрив пользовательский поставщик, который переопределяет выражение поиска значения поля, а другой - без усечения:

class MyOracleProvider : OracleDataProvider
{
    public MyOracleProvider(string name)
        : base(name)
    {
        // original is SetCharField("Char",  (r,i) => r.GetString(i).TrimEnd(' '));
        SetCharField("Char", (r, i) => r.GetString(i));
        // original is SetCharField("NChar", (r,i) => r.GetString(i).TrimEnd(' '));
        SetCharField("NChar", (r, i) => r.GetString(i));
    }
}
...