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データベースが次のスキーマで自動的に作成されます。
ここまでは順調ですね!ただし、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)
のままなので、注釈は無視されているようです。
誰でも助けることができますか?これはかなり一般的な要件であるように思えますが、私の検索は無益です!
既存の答えに費やされた努力に感謝しますが、実際に質問に答えているとは思いませんでした...私はこれをテストして、
[Column(TypeName = "ntext")]
public string Body { get; set; }
(System.ComponentModel.DataAnnotations
)は、ntext型の列を作成するために機能します。
(受け入れられた答えに関する私の問題は、インターフェースの列タイプを変更する必要があることを示しているように見えることですが、問題はプログラムでそれを行う方法です。)
次の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();
}
ntext
を試しましたか? SQL CE 4.0データベースを作成しましたが、手動でテーブルに列を追加すると、text
はデータ型のリストで使用できませんが、ntext
は使用できます。 nvarchar
は選択できますが、varchar
は選択できません。
残念ながら、選択できるnvarchar
の最大サイズは4000です。したがって、nvarchar(max)
もオプションではありません。
文字列の長さ属性の使用に関する問題.
[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)を使用することをお勧めします。
私は知っている、これはおそらく遅すぎる年ですが、:
つかいます:
[StringLength(-1)]
これにより、nTextフィールドが作成されます。 Compact Edition 4.0データベースを使用して、そのフィールドに少なくとも25Kバイトを格納できました。
System.ComponentModel.DataAnnotations.Schema.ColumnAttribute
[Column(TypeName="text")]
public string Text { get; set; }
またはFluent API経由:
modelBuilder.Entity<YourEntityTypeHere>()
.Property( e => e.Text)
.HasColumnType("text");
TypeName = "ntext"
は動作するようですが、私も追加する必要があります:
[StringLength(Int32.MaxValue)]
邪魔になるデフォルトの文字列の長さである128を停止します。
小文字の"text"
? このMSDNディスカッション ごとに、データプロバイダーは大文字と小文字を区別します。
このDataAnnotationは、Code-Firstがsqlでnvarchar(MAX)列を生成するようにします:)
[StringLength(4010)]
このDataAnnotationは、Code-FirstがSQLでnvarchar(MAX)列を生成するようにします
[StringLength(1073741822)]
他の大きな数字が同じかどうかわからない...計算機とnvarchar(MAX)仕様を使用してこれを取得しました。
SQL Server 2005 Expressで試してみましたが、CEではしませんでした
私はそれを使用していますが、それは動作しますが、それが良いアイデアであるか、何かが欠けているかどうかを知りたいです... nvarchar(MAX)が欲しいことをコードファーストに知らせる他の方法はありますか?
すべてのプロパティに注釈を付けたくなく、現代的なEFを使用する場合は、次の規則を使用します。
_public class StringNTextConvention : Convention {
public StringNTextConvention() {
Properties<string>().Configure(p => p.HasColumnType("ntext"));
}
}
_
onModelCreating()
から呼び出すことができます:
_modelBuilder.Conventions.Add(new StringNTextConvention());
_
すべてのstring
sは自動的にntext
列に変わります。
パッケージマネージャーを使用してデータベースの追加と移行を行う場合は、次のように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);