Создайте столбец с varchar (max), а не varchar (8000)

Как создать столбец в таблице и указать его как varchar (max) при использовании servicestack ormlite?

В настоящее время я выполняю некоторые sql после создания таблицы, чтобы получить то, что я хочу. Я видел атрибут StringLength, но задавался вопросом, есть ли более хороший способ сделать это?

Что-то вроде

StringLength(Sql.VarcharMax)

Спасибо

Ответ 1

Работала над проблемой, выполнив следующие

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

Ответ 2

Украсьте свою модель домена System.ComponentModel.DataAnnotations.StringLengthAttribute

таких как

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

или

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

с использованием любой длины, превышающей 8000, чтобы превысить максимальную длину типов столбцов Sql Server varchar/nvarchar, которые требовали объявления MAX.

Использовать пользовательский диалект провайдер понимает объявление 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;
  }
}

Использовать провайдер при создании базы данных factory

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

Примечание. Эта иллюстрация специально предназначена для SqlServer, но она будет актуальна для других поставщиков данных с незначительными изменениями после наследования от нужного провайдера.

Ответ 3

Похоже, что ServiceStack обратился к этому с возможностью дополнительной настройки типа создания полей, см.: https://github.com/ServiceStack/ServiceStack.OrmLite#custom-field-declarations

или как указано в этой ссылке:

Атрибут [CustomField] может использоваться для указания пользовательских объявлений полей в сгенерированных операторах создания таблицы 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 
);  

Опять же, как и в моем комментарии к одному из предыдущих ответов, я предполагаю, что это, вероятно, db-specific, извините, у меня нет простого доступа к нескольким серверам db для тестирования.

Ответ 4

Определение столбца каждого типа можно контролировать с помощью Преобразователи типа OrmLite, где по умолчанию 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) будет автоматически использовать наиболее подходящий тип данных для хранения больших строк в каждой РСУБД.