跨 Table 的關聯性查詢
直接使用物件模型中的關連
如果在資料庫中 Catalog 和 Documents 之間已經建立了關連性(外部索引鍵),在 linq 語法中,此時不需要在 Catalog 和 Documents 之間使用「聯結」(Join), 就可以直接從 Catalog 物件存取 Documents 物件。
// 取得 tblUser , 以執行查詢
Table<tblCatalog> Catalog = db.GetTable<tblCatalog>();
var catalogQuery =
from catalog in Catalog
where catalog.tblDocuments.Any()
select catalog;
foreach (var catalog in catalogQuery)
{
if (catalog.tblDocuments.Count > 0)
{
foreach (var doc in catalog.tblDocuments)
{
Console.WriteLine(" CatalogName={0}, DocumentID={1}, Title={2}", catalog.CName, doc.DID, doc.Title);
}
}
else
{
Console.WriteLine("CatalogName={0}, without documents ...", catalog.CName);
}
}
SELECT [t0].[CID], [t0].[CName], [t0].[ParentCID], [t0].[SortNum], [t0].[CreatedTime], [t0].[CreatedUser], [t0].[RevisedTime], [t0].[RevisedUser]
FROM [tblCatalog] AS [t0]
WHERE EXISTS(
SELECT NULL AS [EMPTY]
FROM [tblDocuments] AS [t1]
WHERE [t1].[CID] = [t0].[CID]
)
上面的 LINQ ,會自動使用延遲載入 (deferred loading) 的功能,也就是預設狀況下只會取得要求的第一層資料,相關連的資料並不會自動取得, 除非後來有要需要使用到第二層的資料,才去資料庫抓取。
Inner Join
從分類中找文章。
Table<tblCatalog> Catalog = db.GetTable<tblCatalog>();
Table<tblDocuments> Documents = db.GetTable<tblDocuments>();
var innerJoin =
from cata in Catalog
join doc in Documents on cata.CID equals doc.CID
where cata.CID == "C0088" || cata.CID == "C0000"
select new { CName = cata.CName, DID = doc.DID, Title = doc.Title };
foreach (var obj in innerJoin)
{
Console.WriteLine("CatalogName={0}, DocumentID={1}, Title={2}", obj.CName, obj.DID, obj.Title);
}
//CatalogName=CSharp, DocumentID=D0048, Title=Properties
//CatalogName=CSharp, DocumentID=D0110, Title=is 和 as
//CatalogName=CSharp, DocumentID=D0124, Title=傳遞參數1
SELECT [t0].[CName], [t1].[DID], [t1].[Title] FROM [tblCatalog] AS [t0] INNER JOIN [tblDocuments] AS [t1] ON [t0].[CID] = [t1].[CID] WHERE ([t0].[CID] = @p0) OR ([t0].[CID] = @p1)
Left Join
從分類中找文章,沒有文章的分類也要列出。
var leftJoin =
from cata in Catalog
join doc in Documents on cata.CID equals doc.CID into k
from doc in k.DefaultIfEmpty()
where cata.CID == "C0088" || cata.CID == "C0000"
select new { CName = cata.CName,
DID = doc == default(tblDocuments) ? "null" : doc.DID,
Title = doc.Title ?? "null"
};
foreach (var obj in leftJoin)
{
Console.WriteLine("CatalogName={0}, DocumentID={1}, Title={2}", obj.CName, obj.DID, obj.Title);
}
//CatalogName=Documents, DocumentID=null, Title=null
//CatalogName=CSharp, DocumentID=D0048, Title=Properties
//CatalogName=CSharp, DocumentID=D0110, Title=is 和 as
//CatalogName=CSharp, DocumentID=D0124, Title=傳遞參數1
SELECT [t0].[CName],
(CASE
WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(5),@p2)
ELSE CONVERT(NVarChar(5),[t2].[DID])
END) AS [DID], COALESCE([t2].[Title],@p3) AS [Title]
FROM [tblCatalog] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[DID], [t1].[CID], [t1].[Title]
FROM [tblDocuments] AS [t1]
) AS [t2] ON [t0].[CID] = [t2].[CID]
WHERE ([t0].[CID] = @p0) OR ([t0].[CID] = @p1)
Group By
從分類中找文章,沒有文章的分類也要列出。
var gooupby =
from cata in Catalog
join doc in Documents on cata.CID equals doc.CID into docs
where cata.CID == "C0088" || cata.CID == "C0000"
select new
{
CName = cata.CName,
Docs = docs
};
foreach (var obj in gooupby)
{
Console.WriteLine("CatalogName={0}, DocCount={1}", obj.CName, obj.Docs.Count());
}
//CatalogName=Documents, DocCount=0
//CatalogName=CSharp, DocCount=3
SELECT [t0].[CName], [t1].[DID], [t1].[CID], [t1].[Title], [t1].[FileName], [t1].[Url], [t1].[Target], [t1].[SortNum], [t1].[Visits], [t1].[CreatedTime], [t1].[CreatedUser], [t1].[RevisedTime], [t1].[RevisedUser], [t1].[SetTop], (
SELECT COUNT(*)
FROM [tblDocuments] AS [t2]
WHERE [t0].[CID] = [t2].[CID]
) AS [value]
FROM [tblCatalog] AS [t0]
LEFT OUTER JOIN [tblDocuments] AS [t1] ON [t0].[CID] = [t1].[CID]
WHERE ([t0].[CID] = @p0) OR ([t0].[CID] = @p1)
ORDER BY [t0].[CID], [t1].[DID]
多欄位 Join
from B in TblCodeBs
join C in TblCodeCs on new {B.CodeA , B.CodeB} equals new {C.CodeA, C.CodeB} into CodeC
from C in CodeC.DefaultIfEmpty()
select new
{
B.CodeA, B.CodeB, CodeC = C.CodeC==null?0:C.CodeC,
BName = B.CodeName,
CName = C.CodeName ?? "NA"
}
-- Region Parameters
DECLARE @p0 Int = 0
DECLARE @p1 NVarChar(1000) = 'NA'
-- EndRegion
SELECT [t0].[CodeA], [t0].[CodeB],
(CASE
WHEN ([t1].[CodeC]) IS NULL THEN @p0
ELSE [t1].[CodeC]
END) AS [CodeC], [t0].[CodeName] AS [BName], COALESCE([t1].[CodeName],@p1) AS [CName]
FROM [tblCodeB] AS [t0]
LEFT OUTER JOIN [tblCodeC] AS [t1] ON ([t0].[CodeA] = [t1].[CodeA]) AND ([t0].[CodeB] = [t1].[CodeB])
Like 查詢
from cata in TblCatalogs
join doc in TblDocuments on cata.CID equals doc.CID into k
from doc in k.DefaultIfEmpty()
where cata.CID.Contains("C0088") || cata.CID.StartsWith("C0088") || cata.CID.EndsWith("C0088")
select new { CName = cata.CName,
DID = doc == default(TblDocuments) ? "NA" : doc.DID,
Title = doc.Title ?? "null"
}
DECLARE @p0 VarChar(1000) = '%C0088%'
DECLARE @p1 VarChar(1000) = 'C0088%'
DECLARE @p2 VarChar(1000) = '%C0088'
DECLARE @p3 NVarChar(1000) = 'NA'
DECLARE @p4 NVarChar(1000) = 'null'
SELECT [t0].[CName],
(CASE
WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(5),@p3)
ELSE CONVERT(NVarChar(5),[t2].[DID])
END) AS [DID], COALESCE([t2].[Title],@p4) AS [Title]
FROM [tblCatalog] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[DID], [t1].[CID], [t1].[Title]
FROM [tblDocuments] AS [t1]
) AS [t2] ON [t0].[CID] = [t2].[CID]
WHERE ([t0].[CID] LIKE @p0) OR ([t0].[CID] LIKE @p1) OR ([t0].[CID] LIKE @p2)

沒有留言:
張貼留言