2012-09-17 8 views
69

私のモデルの1つにASP.NET MVC applicationのデータアノテーションを追加しました。[Required]次のエラーでUpdate-Databaseコマンドの結果を実行し、移行を作成した後:Entity Frameworkの移行で必須フィールドの既定値?

Cannot insert the value NULL into column 'Director', table 'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies'; column does not allow nulls. UPDATE fails. The statement has been terminated.

これは彼らのDirector列にNULLを持つ一部のレコードが原因です。これらの値を自動的にデフォルト(「John Doe」)ディレクターに変更することはできますか?ここで

は私のモデルである:

public class Movie 
    { 
     public int ID { get; set; } 
     [Required] 
     public string Title { get; set; } 

     [DataType(DataType.Date)] 
     public DateTime ReleaseDate { get; set; } 

     [Required] 
     public string Genre { get; set; } 

     [Range(1,100)] 
     [DataType(DataType.Currency)] 
     public decimal Price { get; set; } 

     [StringLength(5)] 
     public string Rating { get; set; } 

     [Required]  /// <--- NEW 
     public string Director { get; set; } 
    } 

、ここでは私の最新の移行です:

public partial class AddDataAnnotationsMig : DbMigration 
{ 
    public override void Up() 
    { 
     AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false)); 
     AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false)); 
     AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); 
     AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false)); 
    } 

    public override void Down() 
    { 
     AlterColumn("dbo.Movies", "Director", c => c.String()); 
     AlterColumn("dbo.Movies", "Rating", c => c.String()); 
     AlterColumn("dbo.Movies", "Genre", c => c.String()); 
     AlterColumn("dbo.Movies", "Title", c => c.String()); 
    } 
} 

答えて

52

私の記憶が正しければ、このような何かが動作するはずです:

AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false, defaultValueSql: "John Doe")); 
+7

私もそう思ったが、それは既存のレコードのための作業を思えません。だから私はまだエラーが発生します。 – drozzy

+0

@drozzy多分バグかもしれません:[EF 4.3.1 Migration Exception - AlterColumn defaultValueSqlは異なるテーブルに対して同じデフォルトの制約名を作成します。](http://stackoverflow.com/questions/9830216/ef-4-3-1 -migration-exception-altercolumn-defaultvaluesql-creates-same-default /)クエリによって 'IS NULL'チェックで行を更新することができます。 – webdeveloper

+0

面白いですが、私は彼らが何を話しているのか分かりません。しかし、これがバグであれば、それは意味をなさないでしょう。 – drozzy

9
public partial class AddDataAnnotationsMig : DbMigration 
{ 
    public override void Up() 
    { 
     AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); 
     AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false,defaultValue:"Genre")); 
     AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); 
     AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false,defaultValue:"Director")); 

    } 

    public override void Down() 
    {  
     AlterColumn("dbo.Movies", "Director", c => c.String()); 
     AlterColumn("dbo.Movies", "Rating", c => c.String()); 
     AlterColumn("dbo.Movies", "Genre", c => c.String()); 
     AlterColumn("dbo.Movies", "Title", c => c.String());  
    } 
} 
+2

ええええと、ありがとうございます。でも、@ webdeveloperの回答とどう違うのですか? – drozzy

+1

デフォルト値パラメータ – Pushpendra

+1

@Pushpendraをどこに追加する必要があるかは教えられていませんが、開発者が一度にそれを忘れる傾向があるのは面白いです。私はすべてのレベルを満たす詳細な答えが好きです。よくできました! – usefulBee

92

@webdeveloperと@Pushpenの回答に加えて既存の行を更新するには、移行に更新を手動で追加する必要があります。例えば:AlterColumnは、テーブル仕様の一部の特定の値にカラムのデフォルトを設定するためにDDLを生成するため

public override void Up() 
{ 
    Sql("UPDATE [dbo].[Movies] SET Title = 'No Title' WHERE Title IS NULL"); 
    AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); 
} 

です。 DDLはデータベース内の既存の行には影響しません。

実際には、同時に2つの変更を行います(デフォルトを設定して列をNOT NULLにする)。それぞれの設定は個別に有効ですが、2つを同時に作成しているため、システムはあなたの意図を「知的に」理解し、すべてのNULLの値をデフォルト値に設定しますが、これは常に期待されるものではありません。

カラムのデフォルト値を設定していて、NOT NULLにしないとします。明らかに、すべてのNULLレコードがあなたが提供するデフォルト値で更新されるとは期待していません。

私の意見では、これはバグではありません。EFが明示的に指示していない方法でデータを更新することは望ましくありません。開発者は、データの処理方法をシステムに指示する必要があります。

+11

Googleを介してこの回答を見つける人々のために:私はEF6でこれを試しましたが、更新ステートメントは必要ありません(これ以上)。彼らは結局バグだと思っています。 – EPLKleijntjens

+1

私はそれを保証することもできます。 null可能なフィールドであってもデフォルト値が必要な場合は、最初にデフォルト値を持つnull不可能な値に変更し、nullableに戻してください。子クラスにヌル値を持たないフィールドを追加したときに非常に便利です:) –

+1

説明にスポットがあります。 AlterColumn()は列の定義を変更するだけです。 – Korayem

5

わからないこのオプションは、常に周りでしたが、ちょうど、同様の問題に遭遇した私は、私が得た

defaultValueSql: "'NY'"

次を使用して手動アップデートを実行せずにデフォルト値を設定することができたことを発見した場合提供された値が "NY"が、私は、彼らが "GETDATE()"のようなSQL値を期待しているので、私は "'NY'"を試してみましたが、それはトリック

は、行全体がこの

のように見えなかったことが実現したエラー0

AddColumn("TABLE_NAME", "State", c => c.String(maxLength: 2, nullable: false, defaultValueSql: "'NY'"));

おかげthis answerに、私はちょうどエンティティプロパティに自動プロパティの初期化子を使用して仕事を得るために十分であることがわかっ

1

右のトラックに私を得ました。例えば

public class Thing { 
    public bool IsBigThing { get; set; } = false; 
} 
+0

既存のレコードには何の影響もありません。(助けてください)データベースにデフォルト値を追加するのではなく、コードの値を設定します。 – chris31389

関連する問題