ADO.Net Entity Frameworkエンティティオブジェクトは、IEntityChangeTrackerの複数のインスタンスから参照することはできません。

ado.net c# entity-framework

質問

私は自分の連絡先を保存しようとしています。これには、ContactRelation(連絡先の関係、既婚、独身、その他)とCountryの参照があります。ただし、連絡先を保存しようとするたびに、 "ADO.Net Entity FrameworkエンティティオブジェクトをIEntityChangeTrackerの複数のインスタンスから参照することはできません"という例外が発生します。

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

私は疎結合MVCデザインをサービスとリポジトリと一緒に使っています。私はこの例外についてたくさんの記事を読んでいますが、どれも私に実用的な答えを与えてくれません...

ありがとう、ピーター

受け入れられた回答

[更新]
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 ;
}

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

Rick StrahlとSamuel Maechamは、リクエストごとにユーザーごとにデータコンテキストを保持する必要があることを教えてくれました。これはWebアプリケーションのHttpContextに入れることを意味します。それについてのすべてを読んで、ここで

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; 
        }
    }
}

人気のある回答

これまでに見たことがあるので、保存する前にReferenceフィールドをEntityKeyに変換し、保存した後にLoadする必要があります。代わりにこのコードを試してください。

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);
  }
}

もちろん、正確なデータベース構造によっては、このコードの一部を変更する必要があるかもしれません。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ