2

웹 사이트에 제품 데이터를 미리로드하고 있습니다. 액세스가 빠를 필요가 있으므로 애플리케이션 시작시 한 번만로드되는 것이 아니라 그것의 요구. 이는 물건을 빨리 넣을 수있는 한 가지 방법입니다. 나는 다른 제품과 나란히 내 제품 엔티티를 로딩하고이를 메모리에 저장하는 것을 열망함으로써이 작업을 수행합니다.더 이상 컨텍스트 참조가 없을 때 컨텍스트에서 엔티티를 분리하는 방법

나는 다음과 같은 무언가가 내 데이터를 검색하려면 다음

public override IEnumerable<Product> Get() 
{ 
    var result = _cacheManager.Get(PreLoadCacheKey) as IEnumerable<Product>; 
    if (result != null) 
     return result; 

    return base.Get(); 
} 

내가 직면하고 문제는 내가 의존성 주입을 사용하여, I보다 (다른 내 데이터 컨텍스트의 범위를 통제하지 않는다는 것입니다 InstancePerRequest()로 설정하고 그대로 두십시오. 따라서 엔터티를 캐시 할 때 여전히 원래 컨텍스트에 대한 참조가 있습니다. 나는 여러 가지를 해봤지만의 문제를 해결받을 수없는 것

:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects. 

나는 데이터베이스에 추가하고 새로운 개체에 캐시에서 검색 엔티티를 연결하려고합니다.

것들 나는 시도했다 :

  1. 이 모든 결과를 통해 반복 AsNoTracking()
  2. 를 사용하여 데이터를 가져 오는 새로운 컨텍스트에 부착 한 후 현재 컨텍스트에서 그들을 보내고 캐시에 추가하고 Detach 전에 캐시에서 검색 할 때.

엔티티의 측면에서 엔티티의 컨텍스트를 분리 할 수 ​​있기를 원합니다. 엔티티가 현재 컨텍스트에 연결되어 있는지 확인하고, 그렇지 않은 경우 이전 엔트리를 분리 할 수 ​​있습니다. 한 개를 새 것으로 부착하십시오. 내가 보았던 것에서, 내가 가질 수없는 낡은 문맥에 대한 언급을하는 것만으로도 그것을 분리 할 수 ​​있습니다.

나는 분명한 뭔가를 놓치고 있습니까?

편집

이 내가 다른 컨텍스트에 엔티티를 첨부 할 것 한 예입니다 : 그것은 순간의 약자로서

var orderLine = order.Lines.FirstOrDefault(ol => ol.Product.Id == product.Id) ?? new SalesOrderLine(); 

orderLine.Price = price.Price; 
orderLine.Product = product; //This is my cache'd entity. 
orderLine.ProductPriceType = price.ProductPriceType; 
orderLine.Quantity += qty; 

order.Customer = customer; 
order.Lines.Add(orderLine); 
order.Status = SalesOrderStatus.Current; 

Update(order); 
SaveChanges(); 

, 내가 강제로 주위를 얻기 위해 캐시되지 않은 버전을로드하고 이 문제.

+0

이 예외가 발생한 코드를 표시하십시오. '제품 '을 다른 주체와 연관 짓는 곳은 어디입니까? –

+0

@GertArnold 완료. – webnoob

답변

0

컨텍스트 개체의 수명을 제어 할 수 없기 때문에로드 할 때 항상 제품 개체를 분리하고 저장할 때이 개체를 첨부하는 것이 좋습니다.

그래서() 메서드가 호출 대신 그냥 캐시 매니저를 확인하고 (base.get에서 돌아 발견되지 않는 경우는 됨) AsNoTracking와 캐시 된 데이터를 가져 오는

public override IEnumerable<Product> Get() 
    { 
     var result = _cacheManager.Get(PreLoadCacheKey) as IEnumerable<Product>; 
     if (result != null) 
      return result; 


     return DetachAndReturn(); 
    } 

    private IEnumerable<Product> DetachAndReturn() 
    { 
     foreach (var product in base.Get()) 
     { 
      base.Detach(product); 
      yield return product; 
     } 
    } 
+0

응답 해 주셔서 감사합니다. 메모리에서 과거에 이것을 시도했을 때 검색된 캐시 엔티티를 현재 컨텍스트에 연결하면 캐시 된 엔티티가 현재 컨텍스트에 대한 참조를 갖게되어 다음에 캐시에서 캐시 엔티티를 검색 할 때 다시 참조하게됩니다. 오래된 문맥. 가능성이 높습니까? 전에 이것을 시도 할 때 직면 한 문제를 오해 한 것일 수 있습니다. – webnoob

1

를 다음을 수행하여 가져 오기 당신을 때 첫 번째 단계. 하지만 (분명히) 캐시에있는 객체는 프록시로 만들어 지므로 다른 컨텍스트에서 생성되었음을 알고 있습니다.당신이 캐시에 개체를 가져 오는 상황에서 프록시 생성을 비활성화하여 않도록

에는 프록시, 그러나 다만 POCO의 캐시되지 않았는지 확인하십시오 :

db.Configuration.ProxyCreationEnabled = false; 

(dbDbContext 인스턴스 인 경우) .

그런 다음 개체를 사용하기 전에 새 컨텍스트에 개체를 연결해야합니다. Add()OrderLine 인 경우 EF에서 새 Product을 추가하려고 할 수 있으므로 중요합니다.

여러분이 엔티티 모델에 OrderLine.ProductId을 노출했다면이 모든 것이 훨씬 쉬울 것이라고 덧붙이고 싶습니다. 단지 Id 값을 설정하는 것만으로 충분할 것입니다.

+0

감사합니다. 마지막 문장에 관해서는,이 경우 완벽하게 이해할 수 있습니다. (그리고 저는 그것을 할 것입니다.)하지만 제품 편집을 할 수있는 또 다른 영역이있어서 현재 제품을 편집하고 값을 변경 한 다음' 업데이트 (제품) '이므로이 경우 도움이되지 않습니다. 이 프록시 물건은 유망한 것처럼 들리므로 (이전에 본 적이없는 이상한) 것을 보겠습니다. – webnoob

관련 문제