31

CreatedDateモデルのエンティティにプロパティを追加しようとしていて、EF5 Code First を使用しています。この日付を一度設定したら変更しないようにしたいのですが、UTC の日付にしたいのです。プロパティを含む抽象クラスから継承したいモデルに多くのエンティティがありCreatedDate、インターフェイスでコンストラクターを強制できないため、コンストラクターを使用したくありません。

さまざまなデータ注釈を試し、特定のエンティティ型を取得して正しいandのgetdate()デフォルト値を持つ変更制約を書き込むデータベース初期化子を作成しようとしましたが、そのコードを正しく作成できませんでした。table_namecolumn_name

AuditDbContext - Entity Framework Auditing ContextまたはEntityFramework.Extendedツールについては紹介しないでください。これらのツールは、私がここで必要とすることを実行しないためです。

アップデート

ViewModel を自分のビューに渡しているため、MyCreatedDateは null になっています。ビューには監査プロパティが正しく呼び出されていません。モデルを自分のビューに渡したとしても、ビューで編集したり保存したりしていません。SaveChanges()CreatedDateCreatedDate

ここで、 を追加できることを読みました。[DatabaseGenerated(DatabaseGeneratedOption.Identity)]これにより、挿入と更新の後に を正しく保存するように EF に指示CreatedDateされますが、アプリケーションで変更することはできません。ただし、Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to OFFこの属性を追加するとエラーが発生します。

この単純なデータベース要件を Code First で実装するのはばかげているため、EF Model First に切り替えようとしています。

4

7 に答える 7

70

これが私がやった方法です:

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

私の移行の Up() メソッドで:

AddColumn("Agents", "CreatedDate", n => n.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));
于 2013-01-18T12:24:49.840 に答える
28

コンテキストで SaveChanges-Method をオーバーライドします。

public override int SaveChanges()
{
  DateTime saveTime = DateTime.UtcNow;
  foreach (var entry in this.ChangeTracker.Entries().Where(e => e.State == (EntityState) System.Data.EntityState.Added))
   {
     if (entry.Property("CreatedDate").CurrentValue == null)
       entry.Property("CreatedDate").CurrentValue = saveTime;
    }
    return base.SaveChanges();

}

コメントが原因で更新されました: 新しく追加されたエンティティのみに日付が設定されます。

于 2013-01-17T18:30:19.443 に答える
4

ここでの主な問題は、SaveChangesを呼び出すたびにCreatedDateが更新され、CreatedDateをビューに渡さなかったため、EntityFrameworkによってNULLまたはMinDateに更新されていたことです。

解決策は単純で、EntityState.AddedのときにCreatedDateを設定するだけでよく、SaveChangesオーバーライドで作業を行う前に、entity.CreatedDate.IsModified = falseを設定するだけで、更新からの変更を無視しました。 Add the CreatedDateは、数行後に設定されます。

于 2013-01-18T04:47:59.937 に答える
4

Stephans's Answerに似ていますが、リフレクションを使用し、すべてのユーザー (外部) 更新の作成/更新時間を無視します。要点を表示

  public override int SaveChanges()
        {
            foreach (var entry in ChangeTracker.Entries().Where(x => x.Entity.GetType().GetProperty("CreatedTime") != null))
            {
                if (entry.State == EntityState.Added)
                {
                    entry.Property("CreatedTime").CurrentValue = DateTime.Now;
                }
                else if (entry.State == EntityState.Modified)
                {
                    // Ignore the CreatedTime updates on Modified entities. 
                    entry.Property("CreatedTime").IsModified = false;
                }

                // Always set UpdatedTime. Assuming all entities having CreatedTime property
                // Also have UpdatedTime
                // entry.Property("UpdatedTime").CurrentValue = DateTime.Now;
                // I moved this part to another foreach loop
            }

            foreach (var entry in ChangeTracker.Entries().Where(
                e => 
                    e.Entity.GetType().GetProperty("UpdatedTime") != null && 
                    e.State == EntityState.Modified || 
                    e.State == EntityState.Added))
            {
                entry.Property("UpdatedTime").CurrentValue = DateTime.Now;
            }

            return base.SaveChanges();
        }
于 2015-06-28T09:39:17.410 に答える
2

Code First は現在、列の既定値を提供するメカニズムを提供していません。

CreatedDate を自動更新するには、基本クラスを手動で変更または作成する必要があります。

public abstract class MyBaseClass
{
    public MyBaseClass()
    {
        CreatedDate = DateTime.Now;
    }
    public Datetime CreatedDate { get; set; }
}
于 2013-01-18T10:47:15.517 に答える
2

EF Core の場合、MS が推奨するソリューションは次の場所にあります: Default Values

DBContext で Fluent API を使用します。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}
于 2018-10-23T07:55:33.260 に答える
-1
Accounts account;
account.Acct_JoinDate = DateTime.Now.ToUniversalTime();
data.Accounts.Add(account);
data.SaveChanges();

モデルの作成時にタイムスタンプを付けてみませんか? ここにあるこれらのアカウントに似ています。

于 2013-01-17T18:19:14.910 に答える