并行Linq查询无法执行

时间:2012-11-08 16:05:32

标签: c# linq plinq

您好我刚刚开始尝试了解Parallel Linq并且在第一次尝试时我没有成功。我使用EF 4.0和我创建的存储库模式类来查询数据。我不相信存储库模式是问题,但我可能会弄错。

我拥有的数据库没有按照我希望的方式设置,但是我继承了系统。我遇到问题的代码如下:

            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的任何帮助,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

对我而言,似乎BaseRepository类使用FindSelect参数创建某种LINQ to Entities查询。

对LINQ to Objects使用AsParellel,其中您的代码实际上评估您传递的表达式。其他LINQ方言,包括LINQ to Entities,转换为与SQL不同的查询语言。 SQL服务器本身可以进行合理的并行化。