안녕하세요 저는 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을 추가하면 나는 다음과 같은 오류가 나타납니다, 그러나 문제없이 실행 :
을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를 사용할 때 도움을 주시면 감사하겠습니다.
'BaseRepository'는'DbContext' 래퍼입니까? dbcontext는 LINQ 쿼리를 사용하여 보내려는 SQL 식을 생성하므로 쿼리를 병렬화하면 도움이되지 않습니다. –
Tejs
내가 기억하는 바로는, 각 병렬 요청 동안 연결을 열고 닫으므로 병렬 쿼리에서 작동하지 않는 동일한 DbContext를 공유합니다. 즉, 동일한 기본 연결을 사용하고 여러 번 열려고 시도하기 때문에 실패합니다 (작동하지 않음). – SPFiredrake
당신은 (당신의 공급자에 의존하는) 질의를 병렬 처리 할 수 있어야합니다. 그러나 PLinq가 그 방법을 알고 있는지는 의심 스럽습니다. 귀하의 오류가 이것을 나타내는 것, 즉각적인 원인은 db가 다중 쿼리 캐싱을 지원하지 않기 때문에 단일 공급자가 병렬 연결을 제공 할 수 없으며 다른 연결을 시도 할 때 오류가 발생한다는 것입니다. 병렬 기능이 정말로 필요한 경우 공급자를 복제 한 다음 쿼리를 멀티 스레딩하여 구식 방식으로 처리 할 수 있습니다. – user1793607