4

エンティティの更新に関して次の問題があります。以下は私のWCFメソッドです。(更新は、更新か追加かを判断した後、パブリックの Save メソッドによって呼び出されます)

protected bool UpdateSalesMaster(SalesMaster order)
{
    using (var context = new MyContext())
    {
        SalesMaster original = context.SalesMasters.FirstOrDefault(o => o.OrderID == order.OrderID);

        if (original != null)
        {
            context.Entry(original).CurrentValues.SetValues(order);

            foreach (SalesDetail detail in order.SalesDetails)
            {
                if (detail.OrderDetailID == 0)
                    context.SalesDetails.Add(detail);
                else
                {
                    SalesDetails originalDetail = context.SalesDetails.FirstOrDefault(o => o.OrderDetailID == detail.OrderDetailID);
                    if (originalDetail != null)
                        context.Entry(originalDetail).CurrentValues.SetValues(detail);
                }
            }

            context.SaveChanges();
            return true;
        }
        else
        {
            throw new FaultException(string.Format("Invalid Order specified: {0}", order.OrderID));
        }
    }
}

SalesMaster で OrderDate を更新するだけで、詳細を変更しないと、データベースに対して更新クエリが実行されて詳細が表示されます。SalesMaster に対してのみ Update クエリが表示されることを期待していました。

誰かが私がここで間違っていることを教えてもらえますか? 何も変更されていない場合、DB に対して更新クエリを実行したくありません。

データベースから元の値を取得するアプローチを使用して、context.Entry(originalDetail).CurrentValues.SetValues(detail); を使用して値が更新されているかどうかを判断します。

また、エンティティの IAuditable 実装をチェックして、SaveChanges をオーバーライドして LastModified 日付を設定します。これは、詳細エンティティの状態が変更済みとして識別されていることを発見したときです。しかし、DB で発生する唯一の更新は、変更の保存で更新された LastModifiedBy です。詳細に何も変更されていないのに、どのように Modified の状態に設定されたのかはわかりません。

public override int SaveChanges()
{
    var changeSet = ChangeTracker.Entries<IAuditable>();

    if (changeSet != null)
    {
        foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
        {
            if (entry.State == EntityState.Added)
                entry.Entity.DateCreated = DateTime.Now;

            if (entry.State == EntityState.Modified)
            {
                entry.Property(a => a.CreatedByUser).IsModified = false;
                entry.Property(a => a.DateCreated).IsModified = false;
            }
            entry.Entity.DateModified = DateTime.Now;
        }
    }
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        throw ex;
    }

}

私のソリューション構造は次のとおりです。

  1. クライアント - Windows フォーム UI
  2. エンティティ - 別のライブラリとしての POCO
  3. WCF - すべてのビジネス ロジック、オブジェクトの追加、更新、削除。
  4. データ - Fluent マッピングを使用した Entity Framework コンテキスト。
4

1 に答える 1