Как указать, что свойство должно генерировать столбец 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)
, поэтому кажется, что аннотация игнорируется.
Может ли кто-нибудь помочь? Это похоже на то, что это должно быть довольно распространенным требованием, но мой поиск оказался бесплодным!
Ответы
Ответ 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.
Ответ 6
Вы можете использовать System.ComponentModel.DataAnnotations.Schema.ColumnAttribute
[Column(TypeName="text")]
public string Text { get; set; }
или через Fluent API:
modelBuilder.Entity<YourEntityTypeHere>()
.Property( e => e.Text)
.HasColumnType("text");
Ответ 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);