导航

利用LINQ 表达式实现跨服务器查询(大数据处理)

Posted on 2010-08-18 16:40  lilin  阅读(2414)  评论(2编辑  收藏  举报

在上一篇博文《利用LINQ 表达式实现跨服务器查询》提到可以联合查询跨服务器的两张表,

实现机制是查询到的实体类Order转化为集合,如代码:List<Order> ol = oq.ToList<Order>();

在利用其集合的扩展方法Join建立两个List的对应关系。如果这时数据量比较大,

就ToList<Order>这一句就十分耗性能了。如果是企业级的数据量,这种方法是行不通的。


那么有没有更好的方法呢?我想到了一种解决方案,与大家分享:

就上篇博文的例子,比如查询到的客户,我们只知道这些客户的定单就行的,其它客户定单没必要查询。查询到的客户如下列代码:
IQueryable
<Customer> cq = from c in customer
where c.City =="Berlin"
select c;

注:LINQ TO SQL 表达式是延迟执行的,也就是先不执行,直到真正需要它的实现值为止。
当然这里查询的数据只在一页上显示就行了。如果数量大可考虑分页问题。
分页可参照:
http://www.cnblogs.com/seebook/archive/2009/02/21/1395310.html
http://www.cnblogs.com/kingkoo/archive/2011/07/26/2116946.html
下面就是关键的了,如何才能查询到客户的定单,用循环定单表吗?等于全表查询并扫描,不行。
我们知道在SQL 语句中 可用 Select * From Orders Where CustomerID ='ANATR' or CustomerID ='ALFKI'来实现我们要的结果
用LINQ 查询表达式这样写:
 IQueryable<Order> oq = order.Where(o => o.CustomerID == "ANATR" || o.CustomerID == "ALFKI");
这种办法查询性能并不高。

SQL 语句 Select * From Orders Where CustomerID ='ANATR' Union All Select * From Orders Where CustomerID ='ALFKI'
要比上面的方法性能高多了,合理利用上了索引。
用LINQ 查询表达式这样写:
            IQueryable<Order> oq = null;
            foreach (Customer c in cl)
            {
                string v = c.CustomerID;
                if (oq == null)
                {
                    oq = order.Where(o => o.CustomerID == v);
                }
                else
                {
                    oq = oq.Concat(order.Where(o => o.CustomerID == v));
                }
            }

            List<Order> ol = oq.ToList<Order>();



上面代码意思就是循环客户表,建立类似Where CustomerID ='ANATR' 这样的条件,再用oq.Concat方法进行联接,
LINQ To SQL 会转化为下列的SQL语名。

可用odb.Log = Console.Out;语句在屏幕上打显示出来,如下:


---------------------------------------
SELECT [t4].[OrderID], [t4].[CustomerID], [t4].[OrderDate]


FROM (
    SELECT [t2].[OrderID], [t2].[CustomerID], [t2].[OrderDate]
    FROM (
        SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[OrderDate]
        FROM [Orders] AS [t0]
        WHERE [t0].[CustomerID] = @p0
        UNION ALL
        SELECT [t1].[OrderID], [t1].[CustomerID], [t1].[OrderDate]
        FROM [Orders] AS [t1]
        WHERE [t1].[CustomerID] = @p1
        ) AS [t2]
    UNION ALL
    SELECT [t3].[OrderID], [t3].[CustomerID], [t3].[OrderDate]
    FROM [Orders] AS [t3]
    WHERE [t3].[CustomerID] = @p2
    ) AS [t4]
-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [BOLID]
-- @p1: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [FISSA]
-- @p2: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [ROMEY]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
-----------------------------
这就是我的解决方法,不对之处请指正。欢迎与大家交流。

原文件下载:App2.rar