Как мне указать, что свойство должно генерировать столбец TEXT, а не nvarchar (4000) - PullRequest
49 голосов
/ 04 февраля 2011

Я работаю с функцией Code First Entity Framework и пытаюсь выяснить, как я могу указать типы данных столбца, которые должны создаваться при автоматической генерации базы данных.

У меня есть простая модель:

public class Article
{
    public int ArticleID { get; set; }

    public string Title { get; set; }
    public string Author { get; set; }
    public string Summary { get; set; }
    public string SummaryHtml { get; set; }
    public string Body { get; set; }
    public string BodyHtml { get; set; }
    public string Slug { get; set; }

    public DateTime Published { get; set; }
    public DateTime Updated { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
}

Когда я запускаю свое приложение, автоматически создается база данных SQL CE 4.0 со следующей схемой:

DB Schema

Пока все хорошо! Однако данные, которые я буду вставлять в свойства Body и BodyHtml, обычно превышают максимально допустимую длину для типа столбца NVarChar, поэтому я хочу, чтобы EF генерировал столбцы Text для этих свойств.

Однако я не могу найти способ сделать это! После долгого поиска в Google и чтения я попытался указать тип столбца, используя DataAnnotations, из информации, найденной в в этом ответе :

using System.ComponentModel.DataAnnotations;

...

[Column(TypeName = "Text")]
public string Body { get; set; }

При этом выдается следующее исключение (при удалении базы данных и повторном запуске приложения):

Schema specified is not valid. Errors: (12,6) : error 0040: The Type text is not qualified with a namespace or alias. Only PrimitiveTypes can be used without qualification.

Но я понятия не имею, какое пространство имен или псевдоним я должен указать, и я не смог найти ничего, что могло бы сказать мне.

Я также попытался изменить аннотацию в соответствии с этой ссылкой :

using System.Data.Linq.Mapping;

...

[Column(DbType = "Text")]
public string Body { get; set; }

В этом случае база данных создается , но столбец Body по-прежнему NVarChar(4000), поэтому аннотация игнорируется.

Кто-нибудь может помочь? Кажется, это должно быть довольно распространенным требованием, но мои поиски были бесплодны!

Ответы [ 12 ]

69 голосов
/ 06 февраля 2011

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

[Column(TypeName = "ntext")]
public string Body { get; set; }

(из System.ComponentModel.DataAnnotations) будет работать для создания столбца типа ntext.

(Моя проблема с принятым ответом заключается в том, что, похоже, это означает, что вам следует изменить тип столбца в интерфейсе, но вопрос заключается в том, как это сделать программно.)

30 голосов
/ 21 марта 2011

Вы можете использовать следующую DataAnnotation, и Code-First сгенерирует тип данных максимального размера, который позволяет база данных. В случае Sql CE это приводит к основному столбцу ntext.

[MaxLength]

или используя EF 4.1 RC свободный API ...

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
        .Property(p => p.Body)
        .IsMaxLength();
}
9 голосов
/ 04 февраля 2011

Вы пробовали ntext?Я только что создал базу данных SQL CE 4.0, и когда я вручную добавляю столбец в таблицу, я замечаю, что text недоступен в списке типов данных, в то время как ntext есть.Точно так же, как вы можете выбрать nvarchar, но не varchar.

К сожалению, самый большой размер nvarchar, который вы можете выбрать, равен 4000. Поэтому nvarchar(max) также не вариант.

There is ntext but no text

6 голосов
/ 23 февраля 2011

Проблема с использованием атрибута длины строки, например

[StringLength(4010)]

Это означает, что любая строка> количество символов, определенных в атрибуте, вызовет исключение проверки, что противоречит любой причине, по которой вы используете неопределенный размер поля в столбце, или вы используете огромное число в атрибут и потерять любую проверку, предлагаемую атрибутом. В конечном итоге вы используете механизм проверки для решения проблемы сопоставления, если вы используете атрибут StringLength, где ответ Марселя Попеску с использованием атрибута Column является гораздо лучшим решением, поскольку он использует атрибуты сопоставления для определения типа и при этом позволяет вам использовать атрибут StringLength для проверки.

Другой вариант - использовать свободный API EF4 CTP5 и определить сопоставление столбцов в событии OnModelCreating в DbContext, например:

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
    .Property(p => p.Body)
    .HasColumnType("nvarchar(max)");
}

Также следует отметить, что NText является устаревшим типом данных ( ntext, text и image (Transact-SQL) MS Books Online ), и вместо него рекомендуется использовать NVarChar (MAX).

5 голосов
/ 08 февраля 2012

Я знаю, это, вероятно, слишком поздно, но:

Использование:

[StringLength(-1)] 

Это создаст поле nText. Мне удалось сохранить не менее 25 Кбайт в этом поле, используя база данных Compact Edition 4.0.

4 голосов
/ 09 октября 2014

Вы можете использовать System.ComponentModel.DataAnnotations.Schema.ColumnAttribute

[Column(TypeName="text")]
public string Text { get; set; }

или через Fluent API:

modelBuilder.Entity<YourEntityTypeHere>()
    .Property( e => e.Text)
    .HasColumnType("text");
1 голос
/ 20 мая 2017

Если вы не хотите аннотировать все свои свойства и используете современный EF, используйте соглашение:

public class StringNTextConvention : Convention {
  public StringNTextConvention() {
    Properties<string>().Configure(p => p.HasColumnType("ntext"));                    
  }
}

Вы можете позвонить с вашего onModelCreating():

modelBuilder.Conventions.Add(new StringNTextConvention());

и все ваши string автоматически превратятся в ntext столбцы.

1 голос
/ 28 марта 2011

Согласитесь, что TypeName = "ntext", кажется, работает, хотя я также должен добавить:

[StringLength(Int32.MaxValue)]

, чтобы остановить мешающую по умолчанию длину строки 128.

1 голос
/ 17 февраля 2011

Эта аннотация данных заставит Code-First сгенерировать столбец nvarchar (MAX) в sql:)

[StringLength(4010)]
1 голос
/ 16 февраля 2011

Эта аннотация данных заставит Code-First сгенерировать столбец nvarchar (MAX) в sql

[StringLength(1073741822)]

Не уверен, что другие большие числа делают то же самое ... Я получил это с помощью калькулятора и спецификации nvarchar (MAX).

Я пробовал с SQL Server 2005 Express или нет, но не с CE

Я использую его, и он работает, но я хотел бы знать, хорошая ли это идея или я что-то упустил ... Есть ли другой способ заставить код сначала узнать, что я хочу nvarchar (MAX )

...