c#父/子DB数据绑定到类的列表

  • 本文关键字:列表 数据绑定 DB c# linq
  • 更新时间 :
  • 英文 :


这是我们用于检索标题左连接到它的行(一个查询)的代码,而不是返回两个结果集(一个为头部,一个为行)从数据库中获取相关数据,我们总是得到一个头部,无论它有多少行。

你能帮我理解为什么如果底部的Distinct()被删除,它将返回与检索的行数相对应的HEAD副本吗?

  1. 这是因为在阅读器的每一行,我们项目一个头,即使它是相同的?所以如果HEAD有40条线,我们将同样的HEAD投射40次?那么一个DISTINCT将消除39,只返回1 ?

  2. 是否只是做。firstordefault()没有Distinct()在这种情况下等同于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();
}
}

这是因为在读者的每一行,我们项目一个头,即使它是相同的?所以如果HEAD有40条线,我们将同样的HEAD投射40次?那么一个DISTINCT将消除39,只返回1 ?

是的,正是这样。您对Select的实现将为reader中的每一行投射一个DTOHead。假设您在结果集中只有一个唯一的"Key",它将始终是相同的DTOHead引用…您创建然后添加到entryDictionary的一个。对Distinct的调用然后删除所有重复项,并为您留下具有一个项目的IEnumerable<DTOHead>

是否只是做。firstordefault()没有Distinct()在这种情况下等同于Distinct(),因为在一天结束时,它正在投射相同的HEAD对象?

既然你指出你的结果集将只包含一个头,那么是的…你可以放弃对Distinct的调用,只使用FirstOrDefault,假设你不想要IEnumerable<DTOHead>,只想要DTOHead的实例。

如果是这种情况,你不需要entryDictionary。您可以从reader中读取第一行,然后使用Select方法将其余行投影到IEnumerable<DTOLine>中。

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;
});
}
}
}
}

相关内容

  • 没有找到相关文章