1.C# Any()和AII()方法
2.为ä»ä¹è¯´LINQè¦èè¿SQL
C# Any()和AII()方法
在处理数据查询时,我们有时需要确认数据是否满足特定条件,或者验证所有数据是否均满足某个条件。比如,在线压缩源码检查某个产品的库存是否已为零,或者确认是否发生了特定交易。
为了实现这一功能,LINQ 提供了两个布尔型方法:Any() 和 All()。这两个方法可以帮助我们快速判断某个条件对数据集来说是 true 还是 false,从而高效地定位数据。
以下是无力源码使用 Visual Studio 创建示例的步骤:
(1)创建一个新的控制台应用程序。
(2)编写 Customer 类的代码,并初始化顾客列表(List<Customer>customers)。
(3)在 Main() 方法中,初始化 customers 列表和查询声明,然后输入以下代码:
(4)编译并执行程序,crackme 源码将看到一些消息,指出一些顾客来自美国,而并非所有顾客都来自亚洲。
示例说明
Customer 类和 customers 列表的初始化与前面例子相同。在第一个查询语句中,zlggui 源码使用了 Any() 方法,通过一个简单的 Lambda 表达式检查 Customer Country 字段的值是否为 USA:
LINQ 方法 Any() 将 Lambda 表达式 c=>c.Country=="USA"应用于 customers 列表中的所有数据,如果列表中存在任意顾客使得 Lambda 表达式为 true,则返回 true。
检查 Any() 方法返回的ppsspp源码布尔结果变量,输出一个消息,显示查询结果。尽管可以通过一些技巧使代码更简洁,但这里的代码更直观,便于理解。anyUSA 被设为 true,因为数据集中确实存在顾客居住在美国,因此看到了消息“Some customers are in the USA”。
在下一个查询语句中,使用了 All() 方法,通过另一个简单的 Lambda 表达式确定所有顾客是否来自亚洲:
LINQ 方法 All() 将 Lambda 表达式应用于数据集,并返回 false,因为存在一些顾客并非来自亚洲。然后根据 allAsia 的值返回相应的消息。
为ä»ä¹è¯´LINQè¦èè¿SQL
å¦æä½ è¿æ²¡ææ²æººäº LINQï¼å°±ä¼æ³è¿æå¥å¤§æå°æªçãSQL 并没æåæï¼ä¸ºä»ä¹è¿è¦å¯¹å®è¿è¡ä¿®è¡¥å¢? 为ä»ä¹æ们è¿éè¦å¦å¤ä¸ç§æ¥è¯¢è¯è¨å¢?æµè¡ç说æ³æ¯ LINQ å C#ï¼æè VBï¼éæå¨äºä¸èµ·ï¼æ èæ¶é¤äºç¼ç¨è¯è¨åæ°æ®åºä¹é´é åä¸ç鸿æ²ï¼åæ¶ä¸ºå¤ä¸ªæ°æ®æºçç»åæä¾äºåä¸çæ¥è¯¢æ¥å£ãè½ç¶è¿äºé½æ¯äºå®ï¼ä½ä» æ¯æ äºçä¸é¨åãæ´éè¦çæ¯ï¼å½è¦å¯¹æ°æ®åºè¿è¡æ¥è¯¢çæ¶åï¼LINQ å¨å¤§å¤æ°æ åµä¸é½æ¯ SQL æ´å ææã
å SQL ç¸æ¯ï¼ LINQ æ´ç®åãæ´æ´èä¸é«çº§ãè¿æ ·åæ´åæ¯æ¿ C# å C++ åæ¯è¾ãççï¼å°½ç®¡ææ¶åä½¿ç¨ C++ ä»ç¶æ¯æ好çéæ©ï¼æ¯å¦ä½¿ç¨ SQL çåºæ¯ï¼ï¼ä½å¨å¤§å¤æ°åºæ¯ä¸ï¼ä½¿ç¨ç°ä»£æ´æ´çè¯è¨èä¸å¿ 为åºå±ç»èæä½å°±æ¯ä¸é¡¹å¤§èå©ã
SQL æ¯ä¸é¨é常å¤èçè¯è¨âåæäº å¹´ãè½ç¶ç»åè¿äºæ æ°æ¤æ©å±ï¼ä½ä»æ¥æ²¡æ被éæ°è®¾è®¡è¿ãè¿å°±ä½¿å¾å®æç¹æ··ä¹±äºâä¸åæ¯ VB6 æè Visual FoxProãä½ ä¹è®¸å·²ç»æ ¢æ ¢åå¾ä¹ æ¯äºæ¤å èçä¸å°ä»»ä½éæ¼çå°æ¹!
让æ们æ¥çä¸ä¸ªä¾åãä½ æ³è¦ç¼åä¸ä¸ªç®åçæ¥è¯¢æ¥è·å客æ·æ°æ®ï¼å¦ä¸ï¼
SELECT UPPER(Name)FROM CustomerWHERE Name LIKE 'A%'ORDER BY Name
ç°å¨å设è¦å°ç»æééçè¿äºæ°æ®æä¾ç»ä¸ä¸ªç½é¡µï¼å¹¶ä¸æ们æ³è·å第 å° è¡æ°æ®ãæ以æ们éè¦ä¸ä¸ªåæ¥è¯¢ï¼
SELECT UPPER(Name) FROM
(
SELECT *, RN = row_number()
OVER (ORDER BY Name)
FROM Customer
WHERE Name LIKE 'A%'
) AWHERE RN BETWEEN AND ORDER BY Name
èå¦æä½ éè¦æ¯æçæ¬ï¼å¨ SQL Server ä¹åçï¼æ´èçæ°æ®åºï¼æ åµä¼æ´ç³ç³:
SELECT TOP UPPER (c1.Name)FROM Customer c1WHERE
c1.Name LIKE 'A%'
AND c1.ID NOT IN
(
SELECT TOP c2.ID
FROM Customer c2
WHERE c2.Name LIKE 'A%'
ORDER BY c2.Name
) ORDER BY c1.Name
è¿æ ·åä¸ä» å¤æèæ··ä¹±ï¼èä¸ä¹è¿èäº DRY ååãå¦ä¸æ¯ä½¿ç¨ LINQ å®ç°ç¸åçæ¥è¯¢åè½ãæ¾ç¶å¨ç®åæ§ä¸æ´èä¸ç¹ï¼
var query =
from c in db.Customers
where c.Name.StartsWith ("A")
orderby c.Name
select c.Name.ToUpper();
var thirdPage = query.Skip().Take();
åªæå½æ们æä¸¾å° thirdPage æ¶ï¼æ¥è¯¢æä¼å®é æ§è¡ãå¨ä» LINQ å° SQL æè Entity Framework çåºæ¯ä¸ï¼ç¿»è¯å¼æä¼å°ï¼æ们ç¨ä¸¤ä¸ªæ¥éª¤ç»åèæçï¼æ¥è¯¢è½¬æ¢æä¸ä¸ª SQL è¯å¥ï¼è¿ä¸ªè¯å¥æ¯éå¯¹å ¶æè¿æ¥çæ°æ®åºæå¡å¨è¿è¡äºä¼åçã
å¯ç»åæ§
æ¨å¯è½å·²ç»æ³¨æå° LINQ çå¦ä¸ä¸ªæ´å¾®å¦ï¼å¾®å¦ä½æä¹é大ï¼ç好å¤ãæ们éæ©äºç»åä¸ç两个æ¥è¯¢æ¥éª¤ï¼
IQueryable<T> Paginate<T> (this IQueryable<T> query, int skip, int take)
{
return query.Skip(skip).Take(take);
}
æ们å¯ä»¥è¿æ ·åï¼
var query = ...
var thirdPage = query.Paginate (, );
æ´éè¦çæ¯ï¼å¨è¿éæ们å¯ä»¥è¿è¡ä»»æçå页æ¥è¯¢ãæ¢è¨ä¹å°±æ¯éè¿ LINQ ä½ å¯ä»¥ææ¥è¯¢å解æä¸é¨åï¼ç¶åå¨ä½ çåºç¨ç¨åºä¸éç¨ã
èå
LINQ å¦ä¸å¥½å¤å°±æ¯ä½ å¯ä»¥ä¸ç¨ JOIN å°±è½è¿è¡å ³ç³»é´æ¥è¯¢ãä¾å¦ï¼æ们æ³è¦ååºææè´ç©å¨ $ æè 以ä¸ï¼å¹¶ä¸å± ä½å¨åçé¡¿ç顾客ãæ们ä¼åå®è®©è´ä¹°é¡¹ç®åï¼ä¹å°±æ¯ç»å ¸çéè´/项ç®éè´åºæ¯ï¼å¹¶ä¸æï¼æ²¡æ顾客记å½çï¼ç°ééå®ä¹åæ¬è¿æ¥ãè¿å°±éè¦å¨å个表ï¼Purchase, Customer, Address 以å PurchaseItemï¼ä¹é´è¿è¡æ¥è¯¢ãä½¿ç¨ LINQï¼è¿æ ·çæ¥è¯¢ä¸è´¹å¹ç°ä¹åï¼
from p in db.Purchases
where p.Customer.Address.State == "WA" || p.Customer == null
where p.PurchaseItems.Sum (pi => pi.SaleAmount) > select p
å°æ¤ä¸åçåè½ç SQL ç¸æ¯è¾ï¼
SELECT p.*FROM Purchase p
LEFT OUTER JOIN
Customer c INNER JOIN Address a ON c.AddressID = a.ID
ON p.CustomerID = c.ID
WHERE
(a.State = 'WA' || p.CustomerID IS NULL)
AND p.ID in
(
SELECT PurchaseID FROM PurchaseItem
GROUP BY PurchaseID HAVING SUM (SaleAmount) >
)
对æ¤ä¾è¿ä¸æ¥æ©å±ï¼å设æ们æ³è¦å°ç»æéæä»·æ ¼è¿è¡éåºæåï¼å¹¶å¨æç»çæå½±ä¸æ¾ç¤ºéå®åçå§å以åæè´ä¹°é¡¹ç®çæ°éãæ们å¯ä»¥èªç¶ä¸éå¤å°è¡¨è¾¾åºè¿äºé件çæ¥è¯¢æ¡ä»¶ï¼
from p in db.Purchases
where p.Customer.Address.State == "WA" || p.Customer == null
let purchaseValue = p.PurchaseItems.Sum (pi => pi.SaleAmount)
where purchaseValue >
orderby purchaseValue descendingselect new
{
p.Description,
p.Customer.SalesPerson.Name,
PurchaseItemCount = p.PurchaseItems.Count()
}
ä¸é¢æ¯ä½¿ç¨ SQL å®ç°ç¸åçæ¥è¯¢ï¼
SELECT
p.Description,
s.Name,
(SELECT COUNT(*) FROM PurchaseItem pi WHERE p.ID = pi.PurchaseID) PurchaseItemCount
FROM Purchase p
LEFT OUTER JOIN
Customer c
INNER JOIN Address a ON c.AddressID = a.ID
LEFT OUTER JOIN SalesPerson s ON c.SalesPersonID = s.ID
ON p.CustomerID = c.ID
WHERE
(a.State = 'WA' OR p.CustomerID IS NULL)
AND p.ID in
(
SELECT PurchaseID FROM PurchaseItem
GROUP BY PurchaseID HAVING SUM (SaleAmount) >
)ORDER BY
(SELECT SUM (SaleAmount) FROM PurchaseItem pi WHERE p.ID = pi.PurchaseID) DESC
æææçæ¯å¯ä»¥å°ä¸è¿° SQL æ¥è¯¢è½¬æ¢åå° LINQï¼æçæçæ¥è¯¢æ¯ä¸åé½ä¼æå»çå¼éå¤ã论åé常ä¼è´´åºè¿æ ·çæ¥è¯¢ï¼é常æ¯éå·¥ä½ççæ¬ï¼ââè¿æ¯ç¨ SQL è¿è¡æèèä¸æ¯ä»¥ LINQ è¿è¡æèçç»æãè¿å°±åæ¯æ¯å° Fortran ç¨åºè½¬æ¢æ C# 6 æ¶ä¼æ±æ¨ GOTO ç笨æè¯æ³ä¸æ ·ã
æ°æ®ä¿®æ´
å¨æ¥è¯¢èåä¸ä»å¤ä¸ªè¡¨éæ©æ°æ® - æç»çç»æä¼æ¯ä¸ä¸ªæå¹³ç以è¡ä¸ºåä½çå ç»ãå¦æä½ ä½¿ç¨äºå¤å¹´ç SQLï¼ä½ å¯è½è®¤ä¸ºè¿ç§äºä¸ä¼åçå¨ä½ 身ä¸ââå®å¯¼è´æ°æ®éå¤ï¼ä»è使å¾ç»æéæ æ³å¨å®¢æ·ç«¯å¾å¥½å°ä½¿ç¨ãæ以å½å®åçæ¶å¾å¾é¾ä»¥æ¥åãä¸æ¤ç¸åï¼LINQ è®©ä½ å¯ä»¥è·åå°ä¼æ´è¿çåå±çº§çæ°æ®ãè¿å°±é¿å äºéå¤ï¼è®©ç»æé容æå¤çï¼èä¸å¨å¤§å¤æ°æ åµä¸ä¹ä¼æ¶é¤è¿è¡èåæä½çå¿ è¦ãä¾å¦ï¼å设æ们æ³è¦æåä¸ç»é¡¾å®¢ï¼æ¯ä¸æ¡è®°å½é½å¸¦ä¸äºå®ä»¬çé«ä»·å¼äº¤æãä½¿ç¨ LINQï¼ä½ å¯ä»¥è¿æ ·åï¼
from c in db.Customers
where c.Address.State == "WA"select new
{
c.Name,
c.CustomerNumber,
HighValuePurchases = c.Purchases.Where (p => p.Price > )
}
HighValuePurchasesï¼å¨è¿éæ¯ä¸ä¸ªéåãç±äºæ们æ¥è¯¢çæ¯ä¸ä¸ªç¸å ³å±æ§ï¼å°±ä¸éè¦è¿è¡èåäºãå æ¤è¿æ¯ä¸ä¸ªå èåè¿æ¯å¤èåçç»èé®é¢å°±è¢«å¾å¥½çæ½è±¡æäºãå¨æ¤ä¾ä¸ï¼å½ç¿»è¯æäº SQLï¼å¯è½å°±æ¯ä¸ä¸ªå¤èåï¼LINQ ä¸ä¼å 为åéåè¿åçæ¯é¶ä¸ªå ç´ å°±æé¤è¡ãå¦ææ们æ³è¦æä¸ä¸ªå¯ä»¥ç¿»è¯æä¸ä¸ªå èåçä¸è¥¿ï¼å¯ä»¥è¿æ ·å:
from c in db.Customers
where c.Address.State == "WA"
let HighValuePurchases = c.Purchases.Where (p => p.Price > )where HighValuePurchases.Any()select new
{
c.Name,
c.CustomerNumber,
HighValuePurchases
}
LINQ è¿éè¿ä¸ç»ä¸°å¯çæä½ç¬¦å¯¹å¹³é¢å¤èåãèªèåãç»æ¥è¯¢ä»¥åå ¶å®åç§ä¸åç±»åæ¥è¯¢è¿è¡äºæ¯æã
åæ°å
å¦ææ们æ³è¦å°ä¹åçä¾ååæ°åä¼å¦ä½å¢ï¼å¦æ¤"WA"ç¶ææ¯ä¸æ¯å°±è¦æ¥èªäºä¸ä¸ªåéå¢? å ¶å®æ们åªè¦åä¸é¢è¿æ ·åå°±å¯ä»¥äº:
string state = "WA";
var query =
from c in db.Customers
where c.Address.State == state
...
ä¸ä¼æ··æ· DbCommand 对象ä¸é¢çåæ°ï¼æè æ å¿ SQL æ³¨å ¥æ»å»ã LINQ çåæ°åæ¯å èãç±»åå®å ¨å¹¶ä¸é«åº¦å¯è¯»çãå®ä¸ä» 解å³äºé®é¢ââèä¸è§£å³å¾å¾ä¸éã
å 为 LINQ æ¥è¯¢æ¶å¯ä»¥è¿è¡ç»åï¼æ以æ们å¯ä»¥ææ¡ä»¶çæ·»å è°è¯ãä¾å¦ï¼æ们ååºä¸ä¸ªæ¹æ³ï¼å¦ä¸ï¼
IQueryable<Customer> GetCustomers (string state, decimal? minPurchase)
{
var query = Customers.AsQueryable();
if (state != null)
query = query.Where (c => c.Address.State == state);
if (minPurchase != null)
query = query.Where (c => c.Purchases.Any (p => p.Price > minPurchase.Value));
return query;
}
å¦ææ们使ç¨ç©ºç state 以å minPurchase å¼è°ç¨äºè¿ä¸ªæ¹æ³ï¼é£ä¹å¨æ们æ举ç»æéçæ¶åå¦ä¸ SQL å°±ä¼è¢«çæåºæ¥ï¼
SELECT [t0].[ID], [t0].[Name], [t0].[AddressID]FROM [Customer] AS [t0]
ä¸è¿ï¼å¦ææ们æå®äº state å minPurchase çå¼ï¼LINQ å° SQL å°±ä¸åªæ¯åæ¥è¯¢æ·»å äºè°è¯ï¼è¿ä¼æå¿ è¦çèåè¯å¥ï¼
SELECT [t0].[ID], [t0].[Name], [t0].[AddressID]FROM [Customer] AS [t0]LEFT OUTER JOIN [Address] AS [t1] ON [t1].[ID] = [t0].[AddressID]WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Purchase] AS [t2]
WHERE ([t2].[Price] > @p0) AND ([t2].[CustomerID] = [t0].[ID])
)) AND ([t1].[State] = @p1)
å 为æ们çæ¹æ³è¿åäºä¸ä¸ª IQueryableï¼æ¥è¯¢å¨æ举å°ä¹å并ä¸ä¼è¢«å®é å°è½¬æ¢æ SQL 并å 以æ§è¡ãè¿æ ·å°±ç»äºè°ç¨è¿ä¸æ¥æ·»å è°è¯ãå页ãèªå®ä¹æå½±çççæºä¼ã
éæç±»åå®å ¨
å¨ä¹åçæ¥è¯¢ä¸ï¼å¦ææä»¬å° state åé声ææäºä¸ä¸ªæ´åæ°èä¸æ¯ä¸ä¸ªå符串ï¼é£ä¹æ¥è¯¢å¯è½å¨ç¼è¯æ¶å°±ä¼æ¥éï¼èä¸ç¨çå°è¿è¡æ¶ãè¿ä¸ªä¹åæ ·éç¨äºæ表åæè ååå¼éçæ åµãè¿å¨éææ¶æä¸ä¸ªå¾å®å¨ç好å¤ï¼å¦æä½ æ²¡æå®ææ头çå·¥ä½ï¼ç¼è¯å¨ä¼ç»åºæ示ã
客æ·ç«¯å¤ç
LINQ è®©ä½ å¯ä»¥è½»æ¾å°å°æ¥è¯¢çä¸äºé¨å转移å°å®¢æ·ç«¯ä¸è¿è¡å¤çã对äºè´è½½è´æ è¾å¤§çæ°æ®åºæå¡å¨ï¼è¿æ ·åå¯å®é æåæ§è½ãåªè¦ä½ æåæ°æ®æ²¡æè¶ è¿æéï¼æ¢è¨ä¹ï¼ä½ è¿æ¯è¦å¨æå¡å¨ä¸åè¿æ»¤ï¼ï¼å°±å¯ä»¥ç»å¸¸æ§å°éè¿æ对ç»æéè¿è¡éæ°æåºã转æ¢ä»¥åéç»çåå转移å°è´è½½è¾å°çåºç¨æå¡å¨ä¸å»ãä½¿ç¨ LINQï¼ä½ éè¦åçå°±æ¯ AsEnumerable() 转移å°æ¥è¯¢ä¹ä¸ï¼èèªé£ä¸ªç¹ä¹åçææäºæ é½å¯ä»¥å¨æ¬å°æ§è¡ã
ä»ä¹æ¶åä¸ç¨ LINQ å»æ¥è¯¢æ°æ®åº
尽管 LINQ çåè½å¼ºå¤§ï¼ä½æ¯å®å¹¶ä¸è½å代 SQLãå®å¯ä»¥æ»¡è¶³ % 以ä¸çéæ±ï¼ä¸è¿ä½ ææ¶ä»ç¶éè¦SQL:
éè¦æå¨è°æ´çæ¥è¯¢ (ç¹æ®æ¯éè¦ä¼ååè¿è¡éå®æ示çæ¶å)ï¼
æäºæ¶åå°è¦ select 临æ¶è¡¨ï¼ç¶ååè¦å¯¹é£äºè¡¨è¿è¡æ¥è¯¢æä½çæ¥è¯¢ï¼
é¢ç¥çæ´æ°ä»¥åæ¹éæå ¥æä½ã
è¿æå°±å¨ç¨å°è§¦åå¨æ¶ï¼ä½ è¿æ¯éè¦ SQLã (尽管å¨ä½¿ç¨ LINQ çæ¶å诸å¦æ¤ç±»çä¸è¥¿å¹¶é常常被éè¦ï¼ä½å¨è¦ä½¿ç¨åå¨è¿ç¨åå½æ°çæ¶åï¼SQL æ¯ä¸å¯æ缺ç)ãä½ å¯ä»¥éè¿å¨ SQL ä¸ç¼å表å¼å½æ°æ¥å° SQL ä¸ LINQ ç»åå¨ä¸èµ·, ç¶åå¨æ´å å¤æç LINQ æ¥è¯¢éé¢è°ç¨è¿äºå½æ°ã
äºè§£ä¸¤é¨æ¥è¯¢è¯è¨å¹¶ä¸æ¯é®é¢ï¼å 为æ 论å¦ä½ä½ é½ä¼æ³è¦å»å¦ä¹ LINQ ç â LINQ å¨æ¥è¯¢æ¬å°éå以å XML DOM çæ¶åé常å®ç¨ãå¦æä½ ä½¿ç¨çä»ç¶æ¯èæ§çåºäº XmlDocument ç DOMï¼LINQ to XML ç DOM æä½ä¼æ¯ä¸ç§å ·ææå§ææçè¿æ¥ã
è¿æå°±æ¯ç¸æ¯äº SQLï¼ LINQ æ´æäºææ¡ï¼æ以å¦æä½ æ³å个ä¸éçæ¥è¯¢ï¼ä½¿ç¨ LINQ ä¼æ¯ SQL æ´å¥½è¾¾æã