2014-04-27 2 views
0

안녕하세요 저는 엔티티 프레임 워크 5를 사용하고 있습니다. 요청, 지역, 태그의 세 가지 모델이 있습니다. Request and RegionsRequest and Tags 사이에 많은 관계가 있습니다. 나는 this을 따라 양식과 같은 마법사를 만들었습니다. 그래서 나는 3 개의 뷰 모델을 가지고있다. 하나의보기 양식은 기본 정보를 얻고 다른 두 양식은 요청과 관련된 태그 (다중 선택) 및 지역 (다중 선택)을 형성합니다. 내가 만들고 각각의 작업오류 방지 : IEntityChangeTracker의 여러 인스턴스에서 엔티티 개체를 참조 할 수 없습니다.

private Request GetRequest() 
    { 
     if (Session["request"] == null) 
     { 
      Debug.WriteLine("New Session Creation"); 
      Session["request"] = new Request(); 
     } 
     Debug.WriteLine("SameSession"); 
     return (Request)Session["request"]; 
    } 

내 컨트롤러 I에 Entities cxt = new Entities();의 단일 인스턴스가 어떤 특정 요청 모델 인스턴스를 전달하기 위해이 기능을 사용하여 각각의 행동에 같은 요청 세션을 통과하기 위해

선택한 영역 및 태그의 ID를 양식에서 가져 와서 요청 개체 인스턴스에 추가하기 위해 db를 쿼리하십시오.

RegionActionResult

long val; 
       foreach (var item in data.Regions) 
       { 
        val = Convert.ToInt64(item); 
        request.Regions.Add(cxt.Regions.Single(r => r.Id == val)); 
       } 

TagActionResult

long val; 
       foreach (var item in data.Tags) 
       { 
        val = Convert.ToInt64(item); 
        request.Tags.Add(cxt.Tags.Single(r => r.Id == val)); 
       }`enter code here` 

그때 나는 마지막 actio를 호출 FinalActionResult

Request_Log request = GetRequest(); 

      cxt.Request.Add(request); 
      cxt.SaveChanges(); 

그래서

처럼 여기에 요청을 저장 n 요청을 저장하면 오류가 발생합니다 An entity object cannot be referenced by multiple instances of IEntityChangeTracker. 엔티티 프레임 워크에 새로운 것이므로 문제가 무엇인지 알 수 없습니다. 나는 문맥 변수 cxt의 단 하나의 인스턴스를 가지고 있는데,이 인스턴스는 요청 객체에 영역과 태그를 추가 한 다음이 동일한 컨텍스트로 저장하여 내가 어떻게 그 하나의 컨텍스트가 더 많은지에 관해서 잃어버린 것입니다. 제 질문이 의미가 있기를 바랍니다.

답변

4

컨트롤러에 Entities cxt = new Entities()이라는 컨텍스트를 만들면 각 웹 요청을 사용하여 ctx 인스턴스를 새로 만들 수 있습니다. 특히 영역을 선택하고 태그를 선택하는 두 가지 마법사 양식에 대한 컨텍스트 인스턴스가 다릅니다. 따라서 cxt.Regions.Single(...)cxt.Tags.Single(...)RegionTag 개의 엔티티를 두 개의 서로 다른 컨텍스트로 검색하고 해당 엔티티를 request 개체 그래프에 추가합니다. 나중에이 개체를 cxt.Request.Add(request) (아마도 세 번째 ctx 인스턴스에도 있음) EF는 RegionTag이 다른 컨텍스트 (일반적으로 일부 virtual 속성으로 인해 프록시 개체 인 경우)에 대한 참조가 있음을 알게됩니다. 금지되어 있으며 예외의 근원입니다.

지역 및 태그를로드하고 저장하기 전에 마지막 컨텍스트에 엔티티를 다시 연결하기 전에 프록시 만들기를 비활성화 할 때 문제를 해결할 수 있습니다. 그러나, 이것은 내 생각에 매우 해커 솔루션입니다. (예를 들어, 마법사 폼에서 다시 게시 된 데이터를 나타내는 간단한 데이터 객체 나 뷰 모델과 같은) 개체에있는 엔티티를 제외하고는 다른 것을 보유하는 것을 선호합니다. 이렇게 문제를 피하고 해당 데이터를 변환합니다. 데이터베이스에 저장하는 마지막 작업에서만 엔터티로 이동합니다.예를 들어

, 세션 값에 필요한 데이터를 저장 - 각 마법사 형태에 대한 하나

Session["request"] = data.SomeRequestData; // your basic request info 
Session["regions"] = data.Regions; // your collection of region IDs 
Session["tags"] = data.Tags; // your collection of tag IDs 

만 최종 결정에 당신이 엔티티에 함께 조각을 넣어 당신이 그것을 할 하나의 컨텍스트 인스턴스 :

var request = new Request(); 

var requestData = Session["request"] as SomeRequestDataModel; 

request.Property1 = requestData.Property1; 
request.Property2 = requestData.Property2; 
// etc., just copy the properties 

long val; 
var regionIDs = Session["regions"] as IEnumerable<string>; 
foreach (var item in regionIDs) 
{ 
    val = Convert.ToInt64(item); 
    request.Regions.Add(cxt.Regions.Single(r => r.Id == val)); // or .Find(val) 
} 

var tagIDs = Session["tags"] as IEnumerable<string>; 
foreach (var item in tagIDs) 
{ 
    val = Convert.ToInt64(item); 
    request.Regions.Add(cxt.Tags.Single(r => r.Id == val)); // or .Find(val) 
} 

cxt.Request.Add(request); 
cxt.SaveChanges(); 

(. 내가 편의상 Session["XXX"]null에 대한 점검을 떠 났어요)이 절차와 당신은 확신 할 수의 일부이며 모든 엔티티 최종 객체 그래프가 동일한 컨텍스트 인스턴스 ctx에 첨부되어 예외가 발생하지 않습니다.

+0

우수 설명. 정말 도움이된다. – flexxxit