通过 nhibernate 对列的价值很大,但在 toad for oracle 中没问题

Value to large for column via nhibernate but ok in toad for oracle

给定 Oracle table 中的这个字段:

ColumnName varchar(255 byte)

给出这个字符串:

-- abcd abcdefghijkl mnokpqrstuvwxy abcd ab abcdefgh abc def abc
abcdef ab.* abcd
abcdefgh ij
abcd abcdefghijkl mn ab ab.cd = ef.abcdefghijk ab ab.cd = ab.cdabe
abcd abcdefghi.jklmnopqrstuvwxyzabc de ef ea.fd = ef.aezerfds
azere
fr.qsdfrtd = 1
fds ad.dfdsq

我们在 toad for oracle 的帮助下使用简单的插入语句将此文本插入到指定列中:效果很好。

但是:如果我们在 nhibernate 的帮助下插入此文本,我们将收到一个 oracle 错误:

ORA-12899: value too large for column [**SNIP**] (actual: 262, maximum: 255)

如果对给定的字符串进行字节计数,这个错误实际上是正确的,我们将得到 262 的计数。

为什么 nhibernate 会失败,为什么 toad for oracle 会成功执行相同的操作?

有没有人遇到过这个问题或与之相关的问题?

编辑

这里值得一提的是,该字符串已在 html 文本区域中提交。这里可能的问题是 return 在浏览器中被计为 1 个字符,但它应该被计为超过 1 个字符,因为在 .net 中它由 \r\n.

表示

所有这些都在 asp.net mvc 场景中。

实际问题:

与nhibernate、oracle无关。 当带有换行符的文本区域发布到 asp.net mvc 的 "backend" 时,我们收到这些换行符作为 \r\n。它算作 2 个字符,这导致 2 个字节 用于数据库保存。

但是在我们的情况下,我们有一个 maxlength=255 html 属性。浏览器将换行符计为 1 个字符。看出区别了吗?

解决方法

我们通过将 \r\n 替换为 \n.

解决了这个问题
public class NewLineModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (result != null && !string.IsNullOrEmpty(result.AttemptedValue) &&
                bindingContext.ModelType == typeof(string))
            {
                var value = result.AttemptedValue;
                var replacedValue = value.Replace("\r\n", "\n");

                return replacedValue;
            }
            return base.BindModel(controllerContext, bindingContext);
        }
    }