web-dev-qa-db-ja.com

プロパティがnvarchar(4000)ではなくTEXT列を生成するように指定するにはどうすればよいですか

Entity FrameworkのCode First機能を使用しており、データベースが自動生成されるときに作成される列データ型を指定する方法を見つけようとしています。

私は単純なモデルを持っています:

_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列を生成する必要があります。

しかし、私はこれを行う方法を見つけることができないようです!グーグルでかなり読んだ後、 this answer にある情報から、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; }
_

この場合、データベースisが作成されますが、Body列はNVarChar(4000)のままなので、注釈は無視されているようです。

誰でも助けることができますか?これはかなり一般的な要件であるように思えますが、私の検索は無益です!

49
Mark Bell

既存の答えに費やされた努力に感謝しますが、実際に質問に答えているとは思いませんでした...私はこれをテストして、

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

System.ComponentModel.DataAnnotations)は、ntext型の列を作成するために機能します。

(受け入れられた答えに関する私の問題は、インターフェースの列タイプを変更する必要があることを示しているように見えることですが、問題はプログラムでそれを行う方法です。)

69
Marcel Popescu

次のDataAnnotationを使用できます。Code-Firstは、データベースが許可する最大サイズのデータ​​型を生成します。 Sql CEの場合、基になるntext列になります。

[MaxLength]

またはEF 4.1 RC fluent APIを使用しています...

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

ntextを試しましたか? SQL CE 4.0データベースを作成しましたが、手動でテーブルに列を追加すると、textはデータ型のリストで使用できませんが、ntextは使用できます。 nvarcharは選択できますが、varcharは選択できません。

残念ながら、選択できるnvarcharの最大サイズは4000です。したがって、nvarchar(max)もオプションではありません。

There is ntext but no text

9
Kristof Claes

文字列の長さ属性の使用に関する問題.

[StringLength(4010)]

属性で定義された文字数を超える文字列は検証例外をトリガーしますが、列で定義されていないフィールドサイズを使用する理由に反するか、属性で巨大な数字を使用して失う属性によって提供される検証。最終的に、StringLength属性を使用する場合、マッピングの問題を解決するために検証メカニズムを使用します。Column属性を使用するMarcel Popescuの回答は、マッピング属性を使用して型を定義するため、検証用のStringLength属性。

別のオプションは、EF4 CTP5 fluent APIを使用し、DbContextのOnModelCreatingイベントで列マッピングを定義することです。

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

また、NTextは非推奨のデータ型( ntext、text、and image(Transact-SQL)MS Books Online )であり、代わりにNVarChar(MAX)を使用することをお勧めします。

6
nakchak

私は知っている、これはおそらく遅すぎる年ですが、:

つかいます:

[StringLength(-1)] 

これにより、nTextフィールドが作成されます。 Compact Edition 4.0データベースを使用して、そのフィールドに少なくとも25Kバイトを格納できました。

5
Johan Plogfeldt

System.ComponentModel.DataAnnotations.Schema.ColumnAttribute

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

またはFluent API経由:

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

TypeName = "ntext"は動作するようですが、私も追加する必要があります:

[StringLength(Int32.MaxValue)]

邪魔になるデフォルトの文字列の長さである128を停止します。

1
Steve Owen

小文字の"text"このMSDNディスカッション ごとに、データプロバイダーは大文字と小文字を区別します。

1
Axarydax

このDataAnnotationは、Code-Firstがsqlでnvarchar(MAX)列を生成するようにします:)

[StringLength(4010)]
1
Bohdan Lyzanets

このDataAnnotationは、Code-FirstがSQLでnvarchar(MAX)列を生成するようにします

[StringLength(1073741822)]

他の大きな数字が同じかどうかわからない...計算機とnvarchar(MAX)仕様を使用してこれを取得しました。

SQL Server 2005 Expressで試してみましたが、CEではしませんでした

私はそれを使用していますが、それは動作しますが、それが良いアイデアであるか、何かが欠けているかどうかを知りたいです... nvarchar(MAX)が欲しいことをコードファーストに知らせる他の方法はありますか?

1
Peto

すべてのプロパティに注釈を付けたくなく、現代的なEFを使用する場合は、次の規則を使用します。

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

onModelCreating()から呼び出すことができます:

_modelBuilder.Conventions.Add(new StringNTextConvention());
_

すべてのstringsは自動的にntext列に変わります。

1
Gábor

パッケージマネージャーを使用してデータベースの追加と移行を行う場合は、次のように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);
0
hsobhy