Подтвердить что ты не робот

Как указать, что свойство должно генерировать столбец TEXT, а не nvarchar (4000)

Я работаю с функцией 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 для этих свойств.

Однако я не могу найти способ сделать это! После довольно многого разговора и чтения я попытался указать тип столбца, используя 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), поэтому кажется, что аннотация игнорируется.

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

[MaxLength]

или с использованием API-интерфейсов EF 4.1 RC...

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

Ответ 3

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

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

There is ntext but no text

Ответ 4

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

[StringLength(4010)]

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

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

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

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

Ответ 5

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

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

[StringLength(-1)] 

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

Ответ 7

Вы пробовали строчный "text"? Per это обсуждение MSDN, поставщик данных чувствителен к регистру.

Ответ 8

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

[StringLength(1073741822)]

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

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

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

Ответ 9

Эта DataAnnotation заставит Code-First генерировать столбец nvarchar (MAX) в sql также:)

[StringLength(4010)]

Ответ 10

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

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

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

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

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

Ответ 11

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

[StringLength(Int32.MaxValue)]

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

Ответ 12

Если вы добавляете-перенастраиваете и обновляете-базу данных с помощью диспетчера пакетов, вы можете изменить таблицу create, добавив storeType следующим образом:

       CreateTable(
            "dbo.Table_Name",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Title = c.String(nullable: false, maxLength: 500),
                    Body = c.String(unicode: false, storeType: "ntext"),
                })
            .PrimaryKey(t => t.ID);