2011-12-11 3 views
2

EF에서 Context 개체를 WCF 메서드로 전달해야합니다.WCF에 Entity Framework 컨텍스트 개체 전달

일반적으로 WCF 메서드에서 Context 개체를 만들고 메서드 호출이 끝나기 전에 처리하기 때문에 대부분의 메서드에서 제대로 작동합니다.

그러나 일부 조회 테이블에 대해 캐싱을 사용할 수 있으므로 Context 개체 (특히 DBContext)를 MVC 컨트롤러에서 내 특정 WCF 메서드로 전달해야합니다. SqlDependency에 대해이 특정 개체를 사용하기 때문에 위 문장에서 수행하는 것보다는이 특정 Context 개체 (Global.asax 파일의 Application_Start 메서드에서 설정 한 개체)를 전달해야합니다. DBContext 개체를 새로 작성하려고하면 데이터베이스 호출 전에 SqlDependency를 활성화해야한다는 오류 메시지가 표시되므로 SqlDependency를 사용할 수 없습니다.

문제는 KnownType 특성 (예 : DBContext 개체)을 올바르게 선언하지 않는 것과 관련이있는 것으로 알고있는 WCF 테스트 클라이언트 도구를 시작하려고 할 때 다음과 같은 오류가 발생한다는 것입니다 (간결하게 줄임) . WCF 프로젝트는 잘 컴파일됩니다. 내 WCF 서비스에서 KnownType을 사용한 적이 없으므로이 특정 부분에 대한 도움이 필요합니다. 그들은 모두 단순한 유형 (int, string 등)입니다.

Error: Cannot obtain Metadata from http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex

If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange

Error URI: http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex Metadata contains a reference that cannot be resolved:

내 WCF 서비스에서 다음 OperationContract를 코드를 가지고 :

[OperationContract] 
     IEnumerable<Category> GetCategories(YeagerTechEntities DbContext); 

내 WCF 서비스에서 다음 DataContract 코드가 마지막으로

namespace YeagerTechModel 
{ 
    [Serializable] 
    [DataContract(IsReference = true)] 
    [KnownType(typeof(YeagerTechEntities))] 
    public partial class Category 
    { 
     public Category() 
     { 
      this.Projects = new HashSet<Project>(); 
     } 

     [DataMember] 
     public short CategoryID { get; set; } 
     [DataMember] 
     public string Description { get; set; } 

     [DataMember] 
     public virtual ICollection<Project> Projects { get; set; } 
    } 

} 

는, 다음 내 WCF입니다 방법 :

public IEnumerable<YeagerTechModel.Category> GetCategories(YeagerTechEntities DbContext) 
     { 
      //YeagerTechEntities DbContext = new YeagerTechEntities(); 

      DbContext.Configuration.ProxyCreationEnabled = false; 

      IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0).AsCached("Categories").ToList(); 
      //IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0); 

      CloseConnection(DbContext); 

      return category; 
     } 
+0

'null'을 반환하도록 코드를 변경하면이 오류가 사라지나요? 'KnownType'도 제거한다면 어떨까요? 한 번에 하나의 잠재적 인 오류 지점을 제거하고 이와 같은 코드를 분리하려고하면 문제를 격리하는 데 도움이됩니다. –

+0

게시 한 오류가 발생한 후 KnowType 특성을 내 DataContract에 넣습니다. – sagesky36

+0

인터페이스에서 컨텍스트를 전달해야한다고 생각하지 않습니다.나는 그것이 직렬화 될 것이라고 생각하지 않으며, 아마도 큰 두통을 일으킬 것이다. 그것을 제거하려고 했습니까 (아마도 당신이 그것을하는 동안 시체를 비우는 것)? 다른 방법을 사용하여 전달할 수 있지만 서버 측에서 해당 선택을 수행해야합니다. –

답변

1

레지스트리/서비스 로케이터 패턴 다음에 싱글 톤 객체가 필요합니다. 이 객체는 전역 객체에 대한 참조를 보유합니다. 예를 들어 응용 프로그램 시작시 SqlDependency을 사용하여 컨텍스트로이 개체를 채우면 레지스트리를 사용하여 컨트롤러의 작업 및 서비스 작업에서이 컨텍스트에 액세스하게됩니다.

어쨌든 매우 조심스럽게 작업하십시오. SqlDependency 및 EF는 상황이 오래 살아갈 수 있기 때문에 함께 재생되지 않습니다. 긴 생활 문맥은 in most cases anti-pattern입니다. 캐시 된 데이터를로드 한 다음 다른 상황에 대해이 컨텍스트를 사용하지 마십시오. 데이터를 수정하거나 캐시되지 않은 관계를로드하는 데 사용하지 마십시오! 엔티티를 첫 번째 질의에서 추적되지 않는 (AsNoTracking 확장 메소드) 쿼리로로드하고 해당 컨텍스트에 대한 프록시 작성 및 지연로드를 해제하십시오.

또한 EF의 쿼리는 항상 데이터베이스에서 실행된다는 점에 유의하십시오. 나는 당신의 AsCached 무엇을 해야하는지 모르겠지만 어떻게 든 그것이 작동합니다 의심. 당신이 필요로하는 것은 아마도 :

var category = DbContext.Categories.Local 
         .Where(p => p.CategoryID > 0) 
         .ToList(); 

나는 EF와 함께 SqlDependency을 사용하지 않을 것입니다. 나는 ADO.NET과 SQL을 직접 사용할 것이다. EF에서 캐싱의 경우, 대부분의 경우에 2 차 레벨 캐시를 사용하기 위해 EF Caching provider을 점검 할 것입니다.

+0

Ladislav, 의견에 감사드립니다. EF 캐싱 제공자에 대해 읽은 후에, 이것은 내가하고 싶은 일에 너무 복잡해 보입니다. additon에서 일부는 작동하고 다른 일부에서는 작동하지 않습니다. EF가 이후 버전에서 캐싱 속성을 내장 할 때까지 기다릴뿐입니다. 4.0이나 4.1 프레임 워크가 나온 이후로 MS가 왜 이와 같은 것을 생각하지 않는지 궁금합니다. 다행스럽게도, 그들은 곧이 프레임 워크에서 이것을 구현할 것이다. 나는 NHibernate에 SQL Dependency 캐시가 내장되어 있다는 것을 알고있다. – sagesky36

관련 문제