2

私は現在、Entity Framework 5 と Code First アプローチを使用Repository<Entity>.Update()するアプリケーションのメソッドを実装する際のデザイン パターンまたはベスト プラクティスを探しています。ASP.NET MVC 4

問題: 私が遭遇した問題は、エンティティがデータベースからクエリされ、ビューに表示されるときに、すべての属性が入力されていない可能性があることです。その結果、repository.Update(entity)メソッドが呼び出されると、メソッドに渡されるエンティティには、Update()null 値を持つバインドされていないプロパティが含まれる場合があります。ただし、データベースにいくつかの値がある場合があります。Customer.Misc以下のコードの例として。

だから問題はここに来ます。このアプローチによれば、ビューにバインドされていないすべてのプロパティは、最初のUpdate()メソッド呼び出し後にデータベースで Null に設定されます。

class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Misc { get; set; }
}

[HttpGet]
public ActionResult Update(int id)
{
    Repository<Customer> repo = new Repository<Customer>();
    return View(repo.GetById(id)); // View only binds Customer.Name
}

[HttpPost]
public ActionResult Update(Customer customer)
{
    Repository<Customer> repo = new Repository<Customer>();
    repo.Update(customer); // Customer.Misc is null
    ...
}

public void Update(TEntity entity)
{
    var entry = DbContext.Entry<TEntity>(entity);
    if (entry.State == EntityState.Detached)
    {
        ObjectContext.ApplyCurrentValues(EntitySetName, entity);
    }
    DbContext.SaveChanges();
}

私が考えることができる解決策:

  • ビューにすべてのエンティティ属性をバインドします。

    • これは実現不可能であると同時に、すべての属性が入力されるため、パフォーマンスの問題が発生する可能性があると思います。
  • null 値がコピーされないように、プロパティ値をコピーするカスタム メソッドを実装します。

    • EntityHelper.CopyNotNullValues(source, target)ソース エンティティの null 値を無視します。これを行うと、必要に応じて値を null に設定できなくなる可能性があります。
  • ビュー モデルを実装し、ドメイン モデルを使用してデータを相互に変換します。

    • これは、これまでのところ私が考えることができる最良のアプローチです。ビュー モデルにバインドされたすべての属性は常に読み込まれます。Update POST では、すべてのビュー モデルの値がドメイン モデルにコピーされます。

これについてのあなたの考えに本当に感謝します。

4

1 に答える 1

0

Entity Framework では、ChangeObjectState または ApplyCurrentValues を使用すると、データが失われます。この場合、この問題を回避する唯一の方法は、入力エンティティをアタッチし、更新するプロパティをマークすることです。以下の例を参照してください。

    public void Update(TEntity entity, string[] updatedProperties)
    {
        DbContext.Entities.Attach(entity);
        var entry = DbContext.Entry<TEntity>(entity);
        for (int i = 0; i < updatedProperties.Length; i++)
        {
            entry.SetModifiedProperty(updatedProperties[i]);
        }
        DbContext.SaveChanges();
    }

    [HttpPost]
    public ActionResult Update(Customer customer)
    {
        Repository<Customer> repo = new Repository<Customer>();
        repo.Update(customer, new string[]{ "Name" }); // Only update name
        ...
    }

それは私が考えることができる最善の解決策です。コードを最小限に抑え、パフォーマンスを向上させたい。簡単で高給の仕事を見つけるのと同じくらい難しい。

于 2013-01-12T19:37:45.353 に答える