0

使用 Linq2db Oracle 提供程序从表中读取固定 CHAR 字符串的值:

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 约束?

4

1 回答 1

0

由于源代码公开可用,找到了解决方案。默认情况下,Linq2Db 在每个 CHAR 和 NCHAR 列上调用表达式 IDataReader.GetString(int).TrimEnd(' ')。然而,这可以通过实现自定义提供程序来轻松定制,该提供程序会覆盖字段值检索表达式,并且不会修剪:

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));
    }
}
于 2020-02-19T18:11:31.873 回答