【问题标题】:Create a column with varchar(max) rather than varchar(8000)使用 varchar(max) 而不是 varchar(8000) 创建列
【发布时间】:2013-06-17 06:24:45
【问题描述】:

使用 servicestack ormlite 时如何在表中创建列并将其指定为 varchar(max)?

目前我在创建表后执行一些 sql 以获得我想要的。 我看过 StringLength 属性,但想知道是否有更好的方法?

类似

StringLength(Sql.VarcharMax)

谢谢

【问题讨论】:

  • 这里有更多详细信息 [ntext-in-servicestack-ormlite][1] [1]:stackoverflow.com/questions/11281726/…
  • 我会对使用 StringColumnDefinition = UseUnicode 的原因感兴趣? "NVARCHAR(4000)" : "VARCHAR(8000)";
  • @FettMo 如果您的意思是为什么 4000 和 8000 - SQL Server Express 中的 varchar 字段的最大值为 8000(除非您使用最大值)。 nvarchar 是 varchar 的两倍,因此最大值为 4000。
  • 不,这意味着更多为什么不使用 max 作为默认值,除非您在例如 StringLength(6789) 中设置限制

标签: ormlite-servicestack


【解决方案1】:

通过执行以下操作解决了该问题

 if (!db.TableExists(typeof(Entity).Name))
 {
   db.CreateTableIfNotExists<Entity>();
   db.ExecuteSql("ALTER TABLE Entity ALTER COLUMN Column VARCHAR(MAX)");
 }

【讨论】:

  • 我喜欢这个答案,但可能值得指出的是,这是特定于 MS SQL 的,不是吗?
【解决方案2】:

System.ComponentModel.DataAnnotations.StringLengthAttribute装饰你的域模型

比如

[StringLengthAttribute(8001)]
public string Markdown { get;set; }

[StringLength(Int32.MaxValue)]
public string Markdown { get;set; }

使用任何大于 8000 的长度来超过需要 MAX 声明的 Sql Server varchar/nvarchar 列类型的最大长度。

使用理解MAX 声明的自定义方言提供程序。

public class MaxSqlProvider : SqlServerOrmLiteDialectProvider
{
  public new static readonly MaxSqlProvider Instance = new MaxSqlProvider ();

  public override string GetColumnDefinition(string fieldName, Type fieldType, 
            bool isPrimaryKey, bool autoIncrement, bool isNullable, 
            int? fieldLength, int? scale, string defaultValue)
  {
     var fieldDefinition = base.GetColumnDefinition(fieldName, fieldType,
                                    isPrimaryKey, autoIncrement, isNullable, 
                                    fieldLength, scale, defaultValue);

     if (fieldType == typeof (string) && fieldLength > 8000)
     {
       var orig = string.Format(StringLengthColumnDefinitionFormat, fieldLength);
       var max = string.Format(StringLengthColumnDefinitionFormat, "MAX");

       fieldDefinition = fieldDefinition.Replace(orig, max);
     }

     return fieldDefinition;
  }
}

在构建数据库工厂时使用提供者

var dbFactory = new OrmLiteConnectionFactory(conStr, MaxSqlProvider.Instance);

请注意,此插图专门针对 SqlServer,但它与其他数据提供者相关,在从所需提供者继承后稍作更改。

【讨论】:

    【解决方案3】:

    ServiceStack 似乎通过进一步自定义字段创建类型的功能解决了这个问题,请参阅:https://github.com/ServiceStack/ServiceStack.OrmLite#custom-field-declarations

    或在该链接中详细说明:

    [CustomField] 属性可用于在生成的 Create table DDL 语句中指定自定义字段声明,例如:

    public class PocoTable
    {
        public int Id { get; set; }
    
        [CustomField("CHAR(20)")]
        public string CharColumn { get; set; }
    
        [CustomField("DECIMAL(18,4)")]
        public decimal? DecimalColumn { get; set; }
    }
    

    在哪里

    db.CreateTable<PocoTable>(); 
    

    生成并执行以下 SQL:

    CREATE TABLE "PocoTable" 
    (
      "Id" INTEGER PRIMARY KEY, 
      "CharColumn" CHAR(20) NULL, 
      "DecimalColumn" DECIMAL(18,4) NULL 
    );  
    

    然而,根据我对先前答案之一的评论,我猜测这可能是特定于数据库的,抱歉,我无法轻松访问多个数据库服务器进行测试.

    【讨论】:

    【解决方案4】:

    可以使用OrmLite's Type Converters 控制每种类型的列定义,其中默认SqlServerStringConverters 将使用VARCHAR(MAX) 用于属性为[StringLength(StringLengthAttribute.MaxText)] 的属性,例如:

    public class PocoTable
    {
        public int Id { get; set; }
    
        [StringLength(StringLengthAttribute.MaxText)]
        public string MaxText { get; set; }
    
        [StringLength(256)]
        public string SmallText { get; set; }
    }
    

    使用StringLengthAttribute.MaxText(或其别名int.MaxValue)将自动使用最合适的数据类型在每个RDBMS中存储大字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-11
      • 2015-05-12
      • 2011-12-09
      • 2011-01-01
      • 2013-08-13
      • 2012-12-30
      相关资源
      最近更新 更多