如何指定一个属性应该生成一个TEXT列而不是nvarchar(4000)

我正在使用entity framework的代码优先function,我想弄清楚如何指定自动生成数据库时应该创build的列数据types。

我有一个简单的模型:

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; } } 

当我运行我的应用程序时,会自动创build一个SQL CE 4.0数据库,并使用以下模式:

DB架构

到现在为止还挺好! 但是,我将插入BodyBodyHtml属性的数据通常大于NVarChar列types的最大允许长度,所以我希望EF为这些属性生成Text列。

但是,我似乎无法find办法做到这一点! 经过相当多的谷歌search和阅读,我试图从这个答案中find的信息使用DataAnnotations指定列types:

 using System.ComponentModel.DataAnnotations; ... [Column(TypeName = "Text")] public string Body { get; set; } 

这将引发以下exception(当数据库被删除并且应用程序重新运行时):

 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; } 

在这种情况下创build一个数据库,但NVarChar(4000)列仍然是一个NVarChar(4000) ,所以似乎注释被忽略。

谁能帮忙? 这似乎应该是一个相当普遍的要求,但我的search一直没有结果!

我很欣赏现有答案中的努力,但是我还没有发现它实际上回答了这个问题…所以我testing了这一点,发现

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

System.ComponentModel.DataAnnotations的一个)将工作来创build一个ntexttypes的列。

(我接受的答案的问题是,它似乎表明你应该改变接口的列types,但问题是如何以编程方式。

您可以使用以下DataAnnotation,Code-First将生成数据库允许的最大数据types。 在Sql CE的情况下,它会产生一个底层的ntext列。

 [MaxLength] 

或者使用EF 4.1 RC fluent API …

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

你尝试过吗? 我刚刚创build了一个SQL CE 4.0数据库,当我手动添加一列到一个表,我注意到text是不可用的数据types列表,而ntext是。 就像你可以selectnvarchar但没有varchar

不幸的是,你可以select最大的nvarchar大小是4000.所以nvarchar(max)也不是一个选项。

有ntext但没有文字

使用string长度属性的问题,例如

 [StringLength(4010)] 

是否是任何string>在属性中定义的字符数将触发一个validationexception,这种情况违背了为什么你会在列上使用一个非定义的字段大小,或者你在属性中使用了一个巨大的数字由属性提供的任何validation。 最终,如果使用StringLength属性,则使用validation机制来解决映射问题,而使用Column属性的Marcel Popescu的答案是一个更好的解决scheme,因为它使用映射属性来定义types,并且仍然允许您使用用于validation的StringLength属性。

另一个select是使用EF4 CTP5 fluent API并在DbContext中的OnModelCreating事件中定义列映射

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

另外应该注意的是,NText是一个不推荐使用的数据types( ntext,text和image(Transact-SQL)MS Books Online ),build议在其位置使用NVarChar(MAX)

您可以使用System.ComponentModel.DataAnnotations.Schema.ColumnAttribute

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

或通过Fluent API:

 modelBuilder.Entity<YourEntityTypeHere>() .Property( e => e.Text) .HasColumnType("text"); 

我知道,这可能是一年太晚了,但是:

使用:

 [StringLength(-1)] 

这将创build一个nText字段。 我使用Compact Edition 4.0数据库在该领域至less存储了25K字节。

你尝试过小写"text"吗? 根据MSDN讨论 ,数据提供者是区分大小写的。

这个DataAnnotation将使Code-First在sql中生成一个nvarchar(MAX)列

 [StringLength(1073741822)] 

不知道其他大数字是否一样…我使用计算器和nvarchar(MAX)规范得到了这个数字。

我已经尝试过与SQL Server 2005 Express,但不是与CE

我使用它,它的工作原理,但我想知道如果这是一个好主意,或者如果我失去了一些东西…是否有任何其他的方式来使代码首先知道我想nvarchar(MAX)?

这个DataAnnotation将使Code-First在sql中生成一个nvarchar(MAX)列也:)

 [StringLength(4010)] 

如果您不想注释所有属性,并使用现代EF,请使用约定:

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

你可以从你的onModelCreating()调用它:

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

所有的string都会自动变成ntext列。

同意TypeName = "ntext"似乎工作,虽然我也必须添加:

 [StringLength(Int32.MaxValue)] 

停止128个string的默认string长度。

如果使用软件包pipe理器进行添加迁移和更新数据库,则可以通过添加storeType来修改create table,如下所示:

  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);