2012-11-08 4 views
0

안녕하세요 저는 Parallel Linq를 처음으로 사용해 보았습니다. 첫 번째 시도에서 성공하지 못했습니다. EF 4.0과 내가 데이터를 쿼리하기 위해 생성 한 저장소 패턴 클래스를 사용하고 있습니다. 저장소 패턴이 문제라고 생각하지 않지만 실수 할 수 있습니다.병렬 Linq 쿼리가 실행되지 않습니다.

내가 가지고있는 데이터베이스가 내가 원하는 방식으로 설정되어 있지는 않지만, 시스템을 상속 받았습니다. 내가 가진 데 문제가있는 코드는 다음과 같습니다 :

  var gId = Sql.ToGuid(Request["ID"]); 

      var lOrdersGridList = new OrdersGridList(); //Class that only contains properties 

      var lOrdersForContact = new BaseRepository<ORDER>() 
       .Find(i => i.ORDERS_CONTACTS.Where(b => b.CONTACT_ID == gId).Count() > 0).AsParallel() 
       .Select(i => 
        new OrdersGridList 
         { 
          ORDER_ID = i.ID, 
          ORDER_NUM = i.ORDER_NUM, 
          SHIPPING_ACCOUNT_ID = i.ORDERS_ACCOUNTS.Where(b => b.ORDER_ID == i.ID && b.ACCOUNT_ROLE == "Ship To").First().ACCOUNT_ID, 
          SHIPPING_ACCOUNT_NAME = i.ORDERS_ACCOUNTS.Where(b => b.ORDER_ID == i.ID && b.ACCOUNT_ROLE == "Ship To").First().ACCOUNT.NAME, 
          SHIPPING_CONTACT_ID = i.ORDERS_CONTACTS.Where(b => b.ORDER_ID == i.ID && b.CONTACT_ROLE == "Ship To").First().CONTACT_ID, 
          SHIPPING_CONTACT_NAME = i.ORDERS_CONTACTS.Where(b => b.ORDER_ID == i.ID && b.CONTACT_ROLE == "Ship To") 
                   .Select(b => new { SHIPPING_CONTACT_NAME = (b.CONTACT.FIRST_NAME + ' ' + b.CONTACT.LAST_NAME) }).First().SHIPPING_CONTACT_NAME, 
          NAME = i.NAME 

         }).DefaultIfEmpty(lOrdersGridList).ToList<OrdersGridList>(); 


      grdMain.DataSource = lOrdersForContact.ToDataTable().DefaultView; //ToDataTable extension function converts the List Object to a datatable. 

내가 AsParallel없이 코드를 실행하면 코드가 내가 AsParallel을 추가하면 나는 다음과 같은 오류가 나타납니다, 그러나 문제없이 실행 :

error message

public class OrdersGridList : EntityObject 
{ 
    public string ORDER_NUM { get; set; } 

    public Guid ORDER_ID { get; set; } 

    public Guid SHIPPING_ACCOUNT_ID { get; set; } 

    public string SHIPPING_ACCOUNT_NAME { get; set; } 

    public Guid SHIPPING_CONTACT_ID { get; set; } 

    public string SHIPPING_CONTACT_NAME { get; set; } 

    public string NAME { get; set; } 
} 

내가 제거하는 경우 :

또한 단지 경우에 당신이 내가 선택 위의 새로 선언하고있는 클래스보고 싶어 내가 어떤 오류가 발생하지 않는 선택에서 데이터를 검색하는 데 사용되는 모든 관계는 :

   var lOrdersForContact = new BaseRepository<ORDER>() 
       .Find(i => i.ORDERS_CONTACTS.Where(b => b.CONTACT_ID == gId).Count() > 0).AsParallel() 
       .Select(i => 
        new OrdersGridList 
         { 
          ORDER_ID = i.ID, 
          ORDER_NUM = i.ORDER_NUM, 
          //SHIPPING_ACCOUNT_ID = i.ORDERS_ACCOUNTS.Where(b => b.ORDER_ID == i.ID && b.ACCOUNT_ROLE == "Ship To").First().ACCOUNT_ID, 
          //SHIPPING_ACCOUNT_NAME = i.ORDERS_ACCOUNTS.Where(b => b.ORDER_ID == i.ID && b.ACCOUNT_ROLE == "Ship To").First().ACCOUNT.NAME, 
          //SHIPPING_CONTACT_ID = i.ORDERS_CONTACTS.Where(b => b.ORDER_ID == i.ID && b.CONTACT_ROLE == "Ship To").First().CONTACT_ID, 
          //SHIPPING_CONTACT_NAME = i.ORDERS_CONTACTS.Where(b => b.ORDER_ID == i.ID && b.CONTACT_ROLE == "Ship To") 
          //         .Select(b => new { SHIPPING_CONTACT_NAME = (b.CONTACT.FIRST_NAME + ' ' + b.CONTACT.LAST_NAME) }).First().SHIPPING_CONTACT_NAME, 
          NAME = i.NAME 

         }).DefaultIfEmpty(lOrdersGridList).ToList<OrdersGridList>(); 

내가 필요한 경우 더 많은 정보를 제공하기 위해보다 더 행복 할 것이다. PLinq를 사용할 때 도움을 주시면 감사하겠습니다.

+0

'BaseRepository '는'DbContext' 래퍼입니까? dbcontext는 LINQ 쿼리를 사용하여 보내려는 SQL 식을 생성하므로 쿼리를 병렬화하면 도움이되지 않습니다. – Tejs

+1

내가 기억하는 바로는, 각 병렬 요청 동안 연결을 열고 닫으므로 병렬 쿼리에서 작동하지 않는 동일한 DbContext를 공유합니다. 즉, 동일한 기본 연결을 사용하고 여러 번 열려고 시도하기 때문에 실패합니다 (작동하지 않음). – SPFiredrake

+1

당신은 (당신의 공급자에 의존하는) 질의를 병렬 처리 할 수 ​​있어야합니다. 그러나 PLinq가 그 방법을 알고 있는지는 의심 스럽습니다. 귀하의 오류가 이것을 나타내는 것, 즉각적인 원인은 db가 다중 쿼리 캐싱을 지원하지 않기 때문에 단일 공급자가 병렬 연결을 제공 할 수 없으며 다른 연결을 시도 할 때 오류가 발생한다는 것입니다. 병렬 기능이 정말로 필요한 경우 공급자를 복제 한 다음 쿼리를 멀티 스레딩하여 구식 방식으로 처리 할 수 ​​있습니다. – user1793607

답변

0

내게는 BaseRepository 클래스가 FindSelect 매개 변수를 사용하여 일종의 LINQ to Entities 쿼리를 만드는 것처럼 보입니다.

AsParellel은 LINQ to Objects에서 사용됩니다. 실제로 코드 의 표현식을 평가합니다. LINQ to Entities, 을 비롯한 다른 LINQ 사투는을 SQL과 같은 다른 쿼리 언어로 변환합니다. SQL Server는 합리적인 병렬 처리 자체를 수행 할 수 있습니다.

관련 문제