這是我們用于檢索與其行(一個查詢)左連接的標題的代碼,而不是回傳兩個結果集(一個用于頭部,一個用于行)以從資料庫中獲取相關資料,我們總是得到一個頭部,但是它有很多行。
您能否幫助我理解為什么如果底部的 Distinct() 被洗掉,它會回傳與檢索到的行數相對應的 HEAD 重復項。
這是因為對于閱讀器中的每一行,我們都會投射一個 HEAD,即使它是相同的?所以如果 HEAD 有 40 條線,我們將相同的 HEAD 投影 40 次?那么 DISTINCT 將消除 39 并僅回傳一個?
在這種情況下,在沒有 Distinct() 的情況下執行 .FirstOrDefault() 是否與 Distinct() 等效,因為在一天結束時,它正在投影相同的 HEAD 物件?
public static IEnumerable<T> Select<T>(this IDataReader dr, Func<T> selector)
{
if (dr == null)
throw new ArgumentException(nameof(dr));
while (dr.Read())
yield return selector();
}
public void Test()
{
DTOHead head = null;
Dictionary<string, DTOHead> entryDictionary = new Dictionary<string, DTOHead>();
using (DbDataReader reader = cmd.ExecuteReader())
{
var head = reader.Select(dr =>
{
DTOHead entry = null;
if (!entryDictionary.TryGetValue((string)dr["Key"], out entry))
{
DTOHead dtoHead = new DTOHead();
dtoHead.Key = (string)dr["Key"]
dtoHead.Description = (string)dr["DESCRIPTION"];
dtoHead.Lines = new List<DTOLine>();
entry = dtoHead;
entryDictionary.Add(entry.Key, entry);
}
if (dr["LINE_NO"] != DBNull.Value)//skip, there are no lines for this one
{
DTOLine dtoLine = new DTOLine();
dtoLine.LineNo = (string)dr["LINE_NO"];
dtoLine.Qty = (string)dr["QTY"];
entry.Lines.Add(dtoLine);
}
return entry;
}).Distinct();
}
}
uj5u.com熱心網友回復:
這是因為對于閱讀器中的每一行,我們都會投射一個 HEAD,即使它是相同的?所以如果 HEAD 有 40 條線,我們將相同的 HEAD 投影 40 次?那么 DISTINCT 將消除 39 并僅回傳一個?
是的,正是這個。您的實施Select將為DTOHead. reader假設"Key"您的結果集中只有一個唯一的,它將始終是相同的DTOHead參考......您創建然后添加到entryDictionary. 然后呼叫將Distinct洗掉所有重復項,并為您留下IEnumerable<DTOHead>一個專案。
在這種情況下,在沒有 Distinct() 的情況下執行 .FirstOrDefault() 是否與 Distinct() 等效,因為在一天結束時,它正在投影相同的 HEAD 物件?
既然您指出您的結果集將只包含 ONE Head 那么是的......您可以放棄呼叫Distinct并只使用FirstOrDefault,假設您不想要IEnumerable<DTOHead>并且只想要DTOHead.
但是,如果是這種情況,則不需要entryDictionary. 您可以從 中讀取第一行,然后使用您的方法reader將剩余的行投影到 an中。IEnumerable<DTOLine>Select
public void Test()
{
DTOHead head = null;
using (DbDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
// Deal with the first row by creating the DTOHead.
head = new DTOHead();
head.Key = (string)reader["Key"];
head.Description = (string)reader["DESCRIPTION"];
head.Lines = new List<DTOLine>();
if (reader["LINE_NO"] != DBNull.Value)//skip, there are no lines for this one
{
// Deal with the first row by creating the first DTOLine.
DTOLine line = new DTOLine();
line.LineNo = (string)reader["LINE_NO"];
line.Qty = (string)reader["QTY"];
head.Lines.Add(dtoLine);
// Project the remaining rows into lines.
head.Lines.AddRange(reader.Select(dr =>
{
DTOLine dtoLine = new DTOLine();
dtoLine.LineNo = (string)dr["LINE_NO"];
dtoLine.Qty = (string)dr["QTY"];
return dtoLine;
});
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/463214.html
