C# 如何指定属性应生成文本列而不是nvarchar(4000)

C# 如何指定属性应生成文本列而不是nvarchar(4000),c#,entity-framework,ef-code-first,sql-server-ce,data-annotations,C#,Entity Framework,Ef Code First,Sql Server Ce,Data Annotations,我正在使用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; }

我正在使用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; }
}
这会引发以下异常(当删除数据库并重新运行应用程序时):

但我不知道应该指定什么名称空间或别名,也找不到任何可以告诉我的信息

我还尝试根据以下内容更改注释:

在本例中,创建了一个数据库,但
Body
列仍然是
NVarChar(4000)
,因此似乎忽略了注释


有人能帮忙吗?这似乎应该是一个相当普遍的要求,但我的搜索一直没有结果

你试过小写的
“text”
?根据,数据提供程序区分大小写。

您是否尝试了
ntext
?我刚刚创建了一个SQL CE 4.0数据库,当我手动向表中添加一列时,我注意到
text
在数据类型列表中不可用,而
ntext
不可用。就像您可以选择
nvarchar
但不能选择
varchar

不幸的是,您可以选择的最大
nvarchar
大小是4000。因此
nvarchar(max)
也不是一个选项


我很感激在现有答案中所做的努力,但我还没有发现它真正回答了这个问题。。。所以我测试了这个,发现

[Column(TypeName = "ntext")]
public string Body { get; set; }
(来自
System.ComponentModel.DataAnnotations
的一个)将用于创建一个ntext类型列


(我对接受答案的问题是,它似乎表明您应该更改接口中的列类型,但问题是如何以编程方式进行更改。)

此DataAnnotation将使代码首先在sql中生成一个nvarchar(MAX)列

[StringLength(1073741822)]
不确定其他大数字是否也这样做。。。我用计算器和nvarchar(MAX)规范得到了这个

我已经用SQLServer2005Express试过了,但没有用CE


我正在使用它,它是有效的,但我想知道这是一个好主意还是我遗漏了什么。。。有没有其他方法让代码首先知道我需要nvarchar(MAX)?

此数据注释将使代码首先在sql中生成nvarchar(MAX)列:)


使用字符串长度属性的问题,例如

[StringLength(4010)]
任何字符串>属性中定义的字符数都将触发验证异常,这与您在列上使用未定义字段大小的任何原因都不符,或者您在属性中使用了大量字符并丢失了属性提供的任何验证。最终,如果使用StringLength属性,您将使用验证机制来解决映射问题,正如Marcel Popescu的回答一样,使用Column属性是一个更好的解决方案,因为它使用映射属性来定义类型,并且仍然允许您使用StringLength属性进行验证

另一个选项是使用EF4 CTP5 fluent API,并在DbContext中的OnModelCreating事件中定义列映射,例如

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
    .Property(p => p.Body)
    .HasColumnType("nvarchar(max)");
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder){

modelBuilder.Entity),建议在其位置使用NVarChar(MAX)

您可以使用以下DataAnnotation,代码首先将生成数据库允许的最大大小的数据类型。对于Sql CE,它将生成一个底层的ntext列

[MaxLength]
或者使用EF 4.1 RC fluent API

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
        .Property(p => p.Body)
        .IsMaxLength();
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder){
modelBuilder.Entity()
.Property(p=>p.Body)
.IsMaxLength();
}

同意
TypeName=“ntext”
似乎有效,但我还必须补充:

[StringLength(Int32.MaxValue)]

要停止默认字符串长度128的妨碍。

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

使用:

这将创建一个nText字段 Compact Edition 4.0数据库。

您可以使用

或通过Fluent API:

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

如果您使用软件包管理器添加迁移和更新数据库,您可以通过添加存储类型来修改创建表,如下所示:

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

如果您不想对所有属性进行注释,并且使用当代EF,请使用约定:

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

你所有的
字符串
都会自动变成
ntext
列。

我已经尝试过了,但是没有任何区别:生成的列仍然是
varchar
+1,但是对于有用的讨论链接,似乎还有一些其他方法我可以尝试——我将进行通读。CE支持文本吗?在“数据类型”列表中,我可以看到ntext,但看不到文本。@Damien,你说得对,谢谢-请将此作为答案添加(并添加到“数据类型”列表的链接)我会接受的。我找不到在线数据类型列表-我必须下载CE BOL进行检查。看起来克里斯托夫·克莱斯添加了一个覆盖相同领域的答案。@Damien-是的,对不起。我开始键入我的答案时没有看到你的评论。我会接受克里斯托夫的答案,然后感谢你们的帮助!这不起作用th SQL CE。请参阅Michael在此处使用[MaxLength]中的答案。当您尝试插入超过4000个字符时,模型验证仍然会引起问题并引发错误,即使数据库设置为ntext,但在读取“字符串”时,它似乎仍会出错类型,它会自动猜测最大长度=4000,忽略数据库中的类型。对于我来说,仍然没有解决。但是您如何定义模型,以便模型验证理解是一个ntext,而不是字符串(默认最大长度=4000)。我已将ntext设置为我的数据库,但在添加超过4000个字符时仍然会出错。我的模型属性是string ty
[StringLength(Int32.MaxValue)]
[StringLength(-1)] 
[Column(TypeName="text")]
public string Text { get; set; }
modelBuilder.Entity<YourEntityTypeHere>()
    .Property( e => e.Text)
    .HasColumnType("text");
       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);
public class StringNTextConvention : Convention {
  public StringNTextConvention() {
    Properties<string>().Configure(p => p.HasColumnType("ntext"));                    
  }
}
modelBuilder.Conventions.Add(new StringNTextConvention());