2009-03-29 11 views
19

ContactRelationへの参照を持つ私の連絡先を保存しようとしています(連絡先、結婚、シングルなどの関係のみ)。 しかし、毎回私は例外を取得検証され、私の連絡先を、保存しようとはADO.Net Entity Framework IEntityChangeTrackerの複数のインスタンスでエンティティオブジェクトを参照することはできません

public Contact CreateContact(Contact contact) 
{ 
    _entities.AddToContact(contact); //throws the exception 
    _entities.SaveChanges(); 
    return contact ; 
} 

私は疎結合MVCを使用しています「ADO.Net Entity Frameworkのエンティティオブジェクトは、IEntityChangeTrackerの複数のインスタンスによって参照することはできません」サービスとリポジトリによる設計 私はこの例外についての記事をたくさん読みましたが、どれも私に取り組んで答えを与える...

ありがとう、 ピーター

答えて

21

[更新] L2Eはあなたがメインのオブジェクトを保存することができます前に、最初にリンクされているすべてのオブジェクトを保存する必要が使用されているので
。これは、そうでなければ、私の例では、連絡先オブジェクトなしでアーティストを作成することになります。これは、データベース設計では許可されていません。
[/更新]

私の実装はうまくいきました。

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Exclude = "Id")] Artist artist, [Bind(Prefix = "Contact")] Contact contact, [Bind(Prefix = "Country")] Country country, [Bind(Prefix = "ContactRelationship")] ContactRelationship contactRelationship) 
{ 
    ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name), "ID", "Name"); 
    ViewData["ContactRelationships"] = new SelectList(new ContactRelationshipService(_msw).ListContactRelationships().OrderBy(c => c.ID), "ID", "Description"); 

    country = _countryService.GetCountryById(country.ID); 
    contact.Country = country; 
    contactRelationship = _contactRelationshipService.GetContactRelationship(contactRelationship.ID); 
    contact.ContactRelationship = contactRelationship; 
    if(_contactService.CreateContact(contact)){ 
     artist.Contact = contact; 
     if (_service.CreateArtist(artist)) 
      return RedirectToAction("Index");   
    } 
    return View("Create"); 
} 

そして、私のContactRepositoryに:

public Contact CreateContact(Contact contact) 
{ 
    _entities.AddToContact(contact); //no longer throws the exception 
    _entities.SaveChanges(); 
    return contact ; 
} 

私も、それは私が今のところ特別なデータクラスを使用していますので、アプリケーション全体で同じコンテキストを維持するために最善であることをこのウェブサイト上で見つけますこれは

です。Rick StrahlとSamuel Maechamは、リクエストごとにユーザーごとにデータコンテキストを保持する必要があることを教えてくれました。これは、WebアプリケーションのHttpContextにそれを置くことを意味します。 は、誰かが私の解決策をご確認正気を喜ばせることができるかどううーん、私は疑問に思うそれについてのすべてをhere

public class Data 
{ 
    public static MyDBEntities MyDBEntities 
    { 
     get 
     { 
      if (HttpContext.Current != null && HttpContext.Current["myDBEntities"] == null) 
      { 
       HttpContext.Current["myDBEntities"] = new MyDBEntities(); 
      } 
      return HttpContext.Current["myDBEntities"] as MyDBEntities; 
     } 
     set { 
      if(HttpContext.Current != null) 
       HttpContext.Current["myDBEntities"] = value; 
     } 
    } 
} 
+1

Peterさん、ありがとうございました。同じソリューションを探すために1時間ほど費やしています。再度ありがとう – Geo

5

私はあなたが参照フィールドを変換する必要があり、前にこれを見てきました保存する前にEntityKeyに保存してから保存してください。代わりにこのコードを試してください:

public Contact CreateContact(Contact contact){ 
    contact.ConvertContactRelationToReference(); 
    _entities.AddToContact(contact); 
    //throws the exception 
    _entities.SaveChanges(); 
    contact.ContactRelation.Load(); 
    return contact; 
} 

public partial class Contact 
{ 
    public void ConvertContactRelationToReference() 
    { 
    var crId = ContactRelation.Id; 
    ContactRelation = null; 
    ContactRelationReference.EntityKey = new EntityKey("MyEntities.ContactRelations", "Id", crId); 
    } 
} 

もちろん、このコードの一部は、正確なデータベース構造に応じて変更する必要があります。

+0

正しい方向に私を指摘してくれてありがとう、受け入れられた答えとして自分の答えを設定すればいいですか? – Peter

+0

もし私があなたを助けたら、あなたは私に票を投げることができます。あなたの歓迎は、選択された答えとして自分自身をマークするが、あなたはそれのための担当者を取得しません。 – bendewey

+0

私は十分な評判があるとすぐに、ありがとう! – Peter

2

をお読みください。これは以下の回答によく似ていますが、DataContext Life Managementに関するRick Strahlのブログを読んだあと、これはWebアプリケーションのスレッドセーフな解決策ではないかと心配しています。

シングルトンパターンを使用してオブジェクトコンテキストにアクセスして、このエラーメッセージを受け取ったインスタンスもラウンドしました。

私はMyObjectContextクラスに以下を追加しました:

// singleton 
private static MyObjectContext context; 
public static MyObjectContext getInstance() 
{ 
    if (context == null) 
    { 
     context = new MyObjectContext(); 
    } 
    return context; 
} 

そして、私ごとのエンティティリポジトリマッパーで代わりにMyObjectContextの新しいインスタンスをインスタンス化するのを私は

var db = MyObjectContext.getInstance(); 

を使用し、私はここに愚かなことですか?それは動作するようです。

+1

あなたは間違っていない、私の答えのシングルトンDataContextは悪いデザインです。 DataContextをシングルトンにする必要がありますが、リクエストごとにユーザーごとに行う必要があります。つまり、WebアプリケーションのHttpContextに配置する必要があります。この記事を参照してください:http://samscode.com/index.php/2009/12/making-entity-framework-v1-work-part-1-datacontext-lifetime-management/ – Peter

+0

素晴らしい、ありがとう – user427875

関連する問題

 関連する問題