분산 캐시와 함께 Entity Framework POCO 지연 로드 사용

Entity Framework는 Microsoft에서 제공하는 매우 인기 있는 개체 관계형 매핑 엔진이며 트래픽이 많은 응용 프로그램에서 점점 더 많이 사용되고 있습니다. 그리고 이러한 트래픽이 많은 애플리케이션 중 상당수는 메모리 내 분산 캐시를 사용하여 제공되는 확장성을 필요로 합니다. 그러나 어떤 경우에는 Entity Framework와 메모리 내 분산 캐시가 호환되지 않습니다. 방법을 설명하겠습니다.

지연 로드 기능과 함께 POCO(Plain Old CLR Objects)와 함께 Entity Framework를 사용하는 경우 Entity Framework는 지연 로드를 수행하기 위한 코드가 포함된 프록시 개체를 동적으로 생성합니다. 그리고 이러한 동적 개체 정의는 응용 프로그램 프로세스 내에만 존재하므로 out-of-process 분산 캐시에 대해 직렬화할 수 없습니다.

다음은 에 대해 생성되는 프록시의 예입니다. Customer 관련 항목에 Entity Framework 지연 로딩을 사용하려는 엔터티 orders. 동적으로 생성된 클래스 이름이 어떻게 나타나는지 확인하십시오. 이 클래스 이름은 응용 프로그램 프로세스 내에서만 사용할 수 있으며 프로세스 외부에서는 알 수 없습니다.

Entity Framework POCO 사용
Entity Framework 지연 로딩에 의해 생성되는 프록시의 예

이제 문제는 분산 캐시가 항상 처리되지 않고 캐시하기 전에 모든 개체를 직렬화해야 하며 이러한 개체가 다른 클라이언트 상자에서 액세스될 때 다른 시스템에서 역직렬화해야 할 수도 있다는 것입니다. 따라서 역직렬화를 위해 두 시스템 모두에서 개체 유형을 알고 있어야 합니다. 그리고 이것은 Entity Framework에서 동적으로 생성된 프록시를 사용하여 불가능합니다. 한 시스템의 애플리케이션 프로세스 내에서만 알려져 있기 때문입니다. 따라서 분산 캐시와 함께 사용하기 위해 Entity Framework에서 프록시 생성을 비활성화하는 것이 유일한 방법이지만 이는 Entity Framework 지연 로드 기능도 손상시키므로 그다지 실용적인 시나리오는 아닙니다.

프록시 없이 Entity Framework POCO 지연 로드를 사용하는 방법은 무엇입니까?

이 문제를 극복하고 Entity Framework를 지연 로딩과 함께 사용하려면 먼저 직렬화 문제를 일으키지 않도록 프록시를 비활성화해야 합니다. 그런 다음 프록시가 꺼져 있으면 Entity Framework에서 지연 로딩을 지원하지 않기 때문에 지연 로딩을 달성하기 위해 애플리케이션에 몇 가지 추가 코드를 삽입해야 합니다.

또한 Entity Framework 지연 로딩 기능을 달성하는 데 도움이 되는 동시에 엔티티의 POCO를 위반하지 않도록 이 추가 코드를 작성해야 합니다. 이 접근 방식에 대해 예를 들어 더 자세히 단계별로 논의해 보겠습니다.

당신이 있다면 Customer 을 가지고 있는 객체 Orders 이를 속성으로 나열하면 지연 로딩이 관련 항목에 액세스하는 방식으로 작동해야 합니다. Orders 고객에 대해 아직 로드되지 않은 경우(Entity Framework 컨텍스트에 존재하지 않음을 의미) Customer 객체는 자동으로 관련 로드를 호출합니다. Orders. 아래 예제를 사용하여 프록시 없이 Entity Framework 지연 로딩을 구현하고 분산 캐시에서도 이를 사용하는 방법을 보여줍니다.

  1. 첫 번째 단계는 Entity Framework 프록시 생성을 끄고 Entity Framework 지연 로드 기능도 끄는 것입니다. 다음 단계에서 지연 로딩 코드를 직접 구현합니다. XNUMXD덴탈의 context.ContextOptions.ProxyCreationEnabled 속성은 기본적으로 true입니다. 이 기능을 끄려면 컨텍스트 개체의 기본 생성자에서 명시적으로 "거짓"으로 설정해야 합니다.
    {
      public NorthwindContext() : base("name=NorthwindContext")
      {
        this.ContextOptions.ProxyCreationEnabled = false;
        this.ContextOptions.LazyLoadingEnabled = false;
      }
    }
    프록시 생성 및 Entity Framework 지연 로드 설정을 비활성화하면 동적 프록시가 더 이상 생성되지 않고 분산 캐시에 직렬화 문제가 발생하지 않습니다. 실제 일반 이전 CLR 개체(POCO) Customer 개체는 Entity 프레임워크에서 사용하므로 문제 없이 분산 캐시에서 캐시 및 검색할 수 있습니다.

  2. 다음 단계는 고객의 관련 주문에 대해 Entity Framework 지연 로드를 달성하는 데 도움이 되는 몇 가지 코드를 도입하는 것입니다. 위에서 언급했듯이 이 코드는 목표를 달성하는 데 도움이 되지만 실제 고객 및 주문 개체가 여전히 POCO(Plain Old CLR Objects)로 유지되도록 해야 합니다.

    이를 위해 Entity 프레임 워크가 정적 인 다른 클래스를 만듭니다. ObjectContext 및 주문에 대한 Entity Framework 지연 로딩 기능에 사용되는 기능. 이 함수는 나중에 실제 고객 POCO 개체에서 참조로 호출됩니다. 다음은 Helper 클래스에 대한 코드 정의입니다.


    namespace Helper
      {
          public class CustomerHelper
              {
                  public static NorthwindContext CurrentContext;
                  static public void DoLazyLoading(Customer customer, List<Order> orders)
                      {
                          if (CurrentContext == null) return; //no lazy loading
                          var query = from o in CurrentContext.Orders where o.CustomerID == customer.CustomerID select o;
                  
                  foreach (Order o in query)
                          { orders.Add(o); }
                    }
                }
    }
  3. 이제 업데이트해야 합니다. Customer 고객에 대한 모든 관련 주문을 지연 로드하는 Entity Framework의 기능을 갖도록 개체를 만듭니다. 다음은 참조로 이 기능을 호출하기 위해 고객 개체 및 주문 목록 getter를 업데이트하는 방법입니다. 당신은 여전히 ​​​​설정해야합니다 OrderLazyLoad 메인 프로그램의 다음 단계에서 수행되는 헬퍼 클래스에 정의된 지연 로딩 기능을 가리키는 메소드.
    namespace MyPOCOs
    {
      [Serializable]
      public class Customer
      {
        public string CustomerID { get; set; }
        public string CompanyName { get; set; }
        public static Action < Customer, List < Order >> OrderLazyLoad = null;
    
        private List < Order > orders; 
        public virtual List< Order > Orders
        {
          get
          {
            if (orders == null)
            {
              orders = new List < Order >();
              OrderLazyLoad(this, orders);
            }
            return orders;
          }
          set
          {
            orders = value;
          }
        }
      }
      [Serializable]
      public class Order…
    }
  4. 이제 이 확장 기능을 사용하려면 실제 프로그램을 변경해야 합니다.
    1. 도우미 클래스에서 개체 컨텍스트를 설정합니다. CustomerHelper.CurrentContext) 모든 엔터티가 동일한 개체 컨텍스트에서 로드되도록 기본 프로그램에서 사용된 것과 동일해야 합니다. 즉, 지연 로드를 위해 도우미 클래스에 정의된 함수와 소비자 프로그램에서 동일한 개체 컨텍스트를 사용하고 있습니다.
      NorthwindContext Context = new NorthwindContext();
      CustomerHelper.CurrentContext = Context;
    2. 당신은 또한 설정 OrderLazyLoad 도우미 지연 로딩 기능을 가리키는 메서드입니다. 당신이 원하지 않기 때문에 이 작업을 수행하는 것이 더 적절한 장소입니다. Customer Helper 클래스 개체를 직접 참조하는 개체입니다.
      Customer.OrderLazyLoad = Helper.CustomerHelper.DoLazyLoading;
  5. 고객을 쿼리한 다음 분산 캐시에 캐시할 수 있는 프로그램을 실행하고 Entity Framework 지연 로딩의 추가 지원으로 관련 주문도 볼 수 있습니다. 프로그램이 액세스할 때마다 Orders 에서 Customer, 유도된 지연 로딩 기능도 호출됩니다.
    static void Main(string[] args)
    {
      Cache mycache = NCache.InitializeCache("mycache");        
      NorthwindContext Context = new NorthwindContext();
      CustomerHelper.CurrentContext = Context;
      Customer.OrderLazyLoad = Helper.CustomerHelper.DoLazyLoading;
    
      var query = from c in Context.Customers where c.CompanyName.StartsWith("b") select c;
      foreach (Customer c in query)
      {
        mycache.Insert(c.CustomerID, c);
        Console.WriteLine("{0}", c.CustomerID);
        foreach (Order order in c.Orders)
        {
          Console.WriteLine("\t{0}", order.OrderDate.ToString());
        }
      }
      Console.ReadLine();
    }

요약

직렬화 문제에 대해 걱정할 필요 없이 Entity Framework에서 사용되는 POCO(Plain Old CLR Objects)를 캐싱하기 위해 분산 캐시를 사용하고 여전히 Entity Framework 지연 로딩의 전체 기능을 사용할 수 있는 접근 방식에 대해 논의했습니다. 이 접근 방식에는 지연 로딩을 달성하기 위한 일부 코드 작성이 포함되지만 본질적으로 Entity 프레임워크 애플리케이션에서 고성능, 확장성 및 안정성과 같은 분산 캐싱의 이점이 있습니다.

© 저작권 Alachisoft 2002 - . 판권 소유. NCache 는 Diyatech Corp.의 등록상표입니다.