如何指定一个属性应该生成一个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数据库,并使用以下模式:
到现在为止还挺好! 但是,我将插入Body
和BodyHtml
属性的数据通常大于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)
也不是一个选项。
使用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);