在上一篇博文《利用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