2010-12-13 5 views
3

こんにちは、私は私のASP.NET MVCのウェブサイトのためのEntityFrameworkを使用していますEntity-Frameworkの例外を更新しますか?

はアップデートといくつかの問題を抱えています。

これは私の更新コードが好きlooka方法です:

using (BissEntities context = new BissEntities()) 
    { 

     if (adCategoryFilter.Id < 1) 
     context.AddToAdCategoryFilter(adCategoryFilter); 
     else 
     context.Refresh(System.Data.Objects.RefreshMode.ClientWins, adCategoryFilter); 

     if (context.SaveChanges() > 0) 
     return true; 
    } 
    return false; 

context.Refreshを実行すると、私は次の例外を取得:

要素のインデックス0でオブジェクトのコレクションにリフレッシュしましたnullのEntityKeyプロパティ値、またはこのObjectStateManagerには関連付けられていません。

Stacktrace : at System.Data.Objects.ObjectContext.RefreshCheck(Dictionary`2 entities, Object entity, EntityKey key) 
    at System.Data.Objects.ObjectContext.AddRefreshKey(Object entityLike, Dictionary`2 entities, Dictionary`2 currentKeys) 
    at System.Data.Objects.ObjectContext.RefreshEntities(RefreshMode refreshMode, IEnumerable collection) 
    at System.Data.Objects.ObjectContext.Refresh(RefreshMode refreshMode, Object entity) 
    at Biss.Models.FilterModel.UpdateCategoryFilter(AdCategoryFilter adCategoryFilter) in C:\Users\Snowman\Documents\Visual Studio 2010\Projects\Biss\Biss\Models\FilterModel.cs:line 86 

これは初めての問題です。まず、データベース内の関係と関係があると考えましたが、影響を受けたテーブルから削除された後も同じ例外が残っていました。

adCategoryFilterはどこから来たのですか?

adCategoryFilterはinstansiated(new)であり、ViewObjectからのデータで埋められます(Webサイトから)。それはフィルタIDのような必要なデータを持っています(データベースを修正するためにフィルタをマップするため)。

私はこの問題をどのように受けているのか、どうすれば解決できるのか説明します。

BestRegards

答えて

5

ので、あなたのASP.NET MVC、ステートレス環境での作業を使用して。つまり、要求が処理を終了すると、「エンティティフレームワークメモリ」または「グラフ」はなくなります。

だから、あなたは明示的に追加または更新したいEFを伝える必要があります。ここで

は、あなたがそれを行う方法は次のとおりです。スタブ技術と呼ばれている

using (BissEntities context = new BissEntities()) 
{ 
    if (adCategoryFilter.Id < 1) 
    context.AdCategoryFilters.AddObject(adCategoryFilter); 
    else { 
    var stub = new AdCategoryFilters { Id = adCategoryFilter.Id }; 
    context.AdCategoryFilters.Attach(stub); 
    context.AdCategoryFilters.ApplyCurrentValues(adCategoryFilter); 
    } 

    context.SaveChanges(); 
} 

つまり、UPDATEしようとしているエンティティと同じエンティティキーを使用して新しいエンティティを作成します(この場合、エンティティキーは「Id」です)。

このスタブを「添付」して(EF内部グラフによって追跡されるように)、このスタブの値をUPDATEするエンティティで上書きし、変更を保存します。

私は、私は、多層アーキテクチャを持っているように、のUpdateModelを使用し、POCOの、カスタムのviewmodelsなどを使用することはできません - (ない - 私のサービス/リポジトリに私が作成したカスタム「のUpdateModel」方法をより複雑な)バージョンの上記の。

また、「ID < 1、それはASP.NET MVCで追加されたIDを使用しないようにしてください。ビュー上でIDをバインドするのを忘れてしまった場合は、0として渡されます。 更新を実行すると、上記のコードではが追加され、が追加されます。

代わりに、より明示的に - 追加/更新のための別個のアクションメソッドを用意してください。

HTH。

4

代わりのさわやかな、オブジェクトを取得し、(MVCコントローラにまたはのUpdateModel)自動マッパーのようなものを使用して、そのプロパティをアップデートしてみてください

のEntityKeyは、IDとは別のものですフードの下で何か他のものが起こっている。新しく作成されたオブジェクトには、問題が発生している場所があります。

パターンがほとんどない(ないC#の男ので、構文を言い訳してください)のようになります:

var context = new MyEntities(); 
var originalObject = context.MyObjectSet.Single(x => x.Id == viewmodel.Id); 
UpdateModel(originalObject); 
context.SaveChanges(); 

の決定的な違いは、新たに取得したオブジェクトは、すべてのEntityKey正しく設定を持っているということです。 idプロパティを有効に使用して新規/既存のオブジェクトを検出できますが、そのプロパティだけでなく、EntityKeyの方が多くあります。

+0

ありがとうございます。しかし、MVCとAutoMapperのUpdateModel(http://automapper.codeplex.com/)の違いは何ですか? – Banshee

+0

わかりませんが、私はどちらかの内部を見ていません。彼らは両方ともリフレクションを使用し、かなり似ていると思う、私は実際にメタデータで更新されるプロパティを明示的にマークする独自のカスタムプロパティを使用します。どちらの方法でも基本的にorigObject.Property = viewModel.Propertyを各プロパティに対して何度も書くことなく保存できます。これは可能な限り有効です。 – RichardW1001

関連する問題