1

既存の CustomerOrder を変更したい CustomerOrder ビューがあります。

私は非常に単純化されたビューモデルを次のようにしています:

        public class CustomerOrderViewModel
    {
        public int ID { get; set; }
        public Customer Customer { get; set; }
        public DateTime Date { get; set; }
        public IEnumerable<OrderRow> OrderRows { get; set; } 

    }

    public class OrderRow
    {
        public int id { get; set; }
        public int price { get; set; }
    }

    public class Customer
    {
        public string Name { get; set; }    
    }

テーブル/フィールドをマッピングするデータベースもあります。

GET アクション メソッドでは、次のように Automapper を使用して注文を読み込みます。

  var customerOrder =  using (var ctx = new My_Entities()) {
                return ctx.CustomerOrders.
                    Include("Orderrows").
                    Include("Customer").
                    Single(o => o.CustomerOrderID == id); 
            }
  var model= AutoMapper.Mapper.DynamicMap<DataAccessLayer.CustomerOrder, CustomerOrderViewModel>(customerOrder);

ビューでは、Knockout を使用してビューモデルにバインドし、そこでユーザーは CustomerOrder を更新できます。これには、顧客情報の編集や新しい注文行の追加などが含まれます。

次に、ポスト バックで、ViewModel を ObjectContext CustomerOrder にマップします。

var customerOrderToBeSaved =
            AutoMapper.Mapper.DynamicMap<CustomerOrderViewModel, CustomerOrder>(
                customerOrderViewModel);
        try
        {
            using (var ctx = new MyEntities())
            {

                ctx.CustomerOrders.Attach(customerOrderToBeSaved);
                ctx.CustomerOrders.ApplyCurrentValues(customerOrderToBeSaved);
                ...
                ctx.SaveChanges();

            }
        }

エラー メッセージが表示されます:同じキーを持つオブジェクトが ObjectStateManager に既に存在します。ObjectStateManager は、同じキーを持つ複数のオブジェクトを追跡できません。

わかりました。理解できます。しかし、これについてどうすればよいですか?既存のオブジェクトを取得して、そのオブジェクトに変更を適用できますか? 古いものを調べて切り離そうとしましたが、うまくいきません。おそらく、これを完全に間違った方法で行っています。ご意見をお聞かせください。

4

2 に答える 2

3

の引数については、MSDNcustomerOrderToBeSavedを参照してください。ApplyCurrentValues

元のオブジェクトに適用するプロパティの更新を含む分離されたオブジェクト。

したがって、エンティティをデータベースからコンテキストにロードしてからApplyCurrentValues、新しい値を持つ切り離されたオブジェクトをロードする必要があります。

于 2013-03-02T11:49:41.227 に答える
1

更新するためにデータベースから行をロードする必要はありません

あなたはこのようなことをすることができます:

var entity = ctx.CustomerOrders.Attach(customerOrderToBeSaved);
ctx.Entry( entity ).State = EntityState.Modified;
ctx.SaveChanges();

これにより、EFは、レコード内のすべての列を上書きするUPDATESQLステートメントを発行するようになります。

次のように、更新する列を選択できます。

var entity = ctx.CustomerOrders.Attach(customerOrderToBeSaved);

var entry = ctx.Entry( entity );
entry.Property( o => o.<ColumnPropertyToUpdate> ).IsModified = true;
entry.Property( o => o.<ColumnPropertyToUpdate> ).IsModified = true;
...

ctx.SaveChanges();

これを行うと、EFには、UPDATEステートメントで変更済みとしてマークされた列のみが含まれます。

于 2013-03-02T12:07:21.583 に答える