web-dev-qa-db-ja.com

EntityFrameworkが列をデフォルト値で更新しない

EntityFramework 4(EF)を介してSQL Server dbにオブジェクトを挿入しています。受信テーブルには(CreatedDate)の列があり、そのデフォルト値はgetdate()に設定されています。したがって、その値がSQL Serverによってgetdate()にデフォルト設定されると想定して、EFに提供しません。

しかし、これは起こりません。代わりに、EFは検証エラーn SaveChanges()を返します。

このことについてあなたが知っている理由はありますか?私にお知らせください。

どうもありがとう。

22
t_plusplus

(作成日などで)その値を編集したくない場合は、以下を使用できます。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual DateTime CreatedDate { get; set; }

これは、値がデータベースによって制御されていることをEntity Frameworkに伝えますが、それでも値をフェッチします。

その場合、その値を変更できないため、単に初期値が必要な場合の解決策ではないことに注意してください。

デフォルト値だけが必要で、それでも編集が許可されている場合、またはEntity Framework 5以前を使用している場合は、コードでデフォルトを設定する必要があります。

これについてのより多くの議論はここにあります:

Entity Frameworkのデータベースからデフォルトの列値を使用する方法

14
mattmanser

この問題に対する正しい答えは、Entity Frameworkに列が計算済みであることを伝えることです。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual DateTime CreatedDate { get; set; }

DatabaseGeneratedOption.Computedは、データベースによって設定され、Entity Frameworkによって変更できないことを意味します。 DatabaseGeneratedOption.Identityは、列が [〜#〜] identity [〜#〜] 列であることを意味します。これは、数値の主キーの自動インクリメントにのみ使用する必要があります。

** DatabaseGeneratedOption列挙 のドキュメントでは、IDENTITY列については何も言及されていないことに注意してください(これはSqlServer固有の実装の詳細であるためです)。代わりに、Identityオプションを「行が挿入されるとデータベースが値を生成する」と定義します。私は実際には、レコードの作成時にDEFAULT制約を使用してModDateを設定できるようにする方法を探していましたが、レコードの更新時にそれをEntity Frameworkから変更できるようにしました。そのため、説明が原因で解決策が見つかるかもしれないと思いましたが、DatabaseGeneratedOption.Identityのフラグが付けられているレコードのModDateを変更しようとすると例外がスローされました。だから運がありません。

2
CptRobby

エンティティオブジェクト定義の列フィールドに[DatabaseGenerated(DatabaseGeneratedOption.Identity)]属性を適用するだけです。

例えば:

public class SomeTable
{
    ...

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime CreatedDate { get; set; }

    ...
}

これにより、Entity Frameworkに、列の初期値がデータベースによって提供されることが通知されます。行の挿入後、値はデータベースから自動的に更新されます。

2
kkahl

これを使ってみてください。

public virtual DateTime CreatedDate { get; set; } = new Datetime();