2012-01-20 11 views
0

私はObjectDataSourceを持っています。EFを更新して保存するビジネスレイヤメソッドを呼び出します。私はこの奇妙な問題を抱えています。以下のODSマークアップです:DbContext/ObjectDataSource更新の問題

<asp:ObjectDataSource ID="odsDeviceForm" runat="server" ypeName="Spectre.BLL..DeviceManager" 
    DataObjectTypeName="Model.Device" SelectMethod="GetById" 
    InsertMethod="Insert" oninserting="OnItemInserting" UpdateMethod="UpdateEx" 
    oninserted="OnItemInserted" onupdated="OnItemUpdated" 
    onupdating="OnItemUpdating" onobjectcreated="OnOdsObjectCreated" 
    onselected="OnOdsItemSelected" ConflictDetection="CompareAllValues" OldValuesParameterFormatString="orig{0}" > 
    <SelectParameters> 
    <asp:SessionParameter Name="primaryKey" SessionField="SelectedDeviceId" Type="Int32" /> 
    </SelectParameters> 

BLLとrepositoryCode以下の通りです: BLL:

public void UpdateEx(T entity, T origentity) 
{ 
    try 
    { 
    repository.Update(origentity, entity); 
    repository.Save(); 
    } 
    catch (Exception) 
    { 
    throw; 
    } 
} 

リポジトリ:

public void Update(T orig, T newEntity) 
{ 
    myContext.Entry<T>(newEntity).CurrentValues.SetValues(newEntity); 

} 

このコードは、私は例外を取得実行すると:

メンバー 'エンティティ'がエンティティに存在しないため、このタイプのエンティティに対して 'CurrentValues'を呼び出すことはできません。コンテクストに エンティティを追加するには、DbSetのAddメソッドまたはAttachメソッドを呼び出します。

ただし、dbset.attachを実行すると、エンティティがすでに存在するという例外が発生します。

私は何ができるのかわかりませんが、私にとっては循環的な問題のようです。私はこの上に私の髪を引っ張る半分大げさに行ってきました。助けてください。

答えて

0

すでにコンテキストにロードされているデバイスクラス内のナビゲーションプロパティの新しいインスタンスを作成した可能性があります。例えば

device.Foo = new Foo { Id = 1 }; 
context.Devices.Attach(device); 

コンテキストは既にId=1Fooインスタンスを有することができます。したがって、Deviceを添付すると、Fooもアタッチしようとしますが、コンテキストによってすでにトラッキングされている一致するインスタンスが存在するため、失敗します。

可能であれば、スカラープロパティのみを設定してみてください。 Fooインスタンスが

var foo = context.ObjectStateManager 
    .GetObjectStateEntries(EntityState.Added | EtityState.Modified | EntityState.Unchanged) 
    .Select(s => s.Entity).OfType<Foo>().SingleOrDefault(f => f.Id == device.FooId); 

if (foo != null) 
{ 
    // foo is loaded 
} 

またはコンテキストは、ナビゲーションプロパティをロードし、その場合は、そのインスタンスを使用しているかどうかを確認するロードされているかどうかを判断するために

device.FooId = 1; 
context.Devices.Attach(device); 

+0

これがロードされているかどうかを確認するにはどうすればよいですか? – ASR

+0

@ user875615編集された回答を参照してください。 – Eranga