C# 如何从SQL中读取父数据和子数据?
再次感谢您发布的所有精彩答案 我有两个SQL表。第一个定义父级,并有一个名为ParentId的主键列。我还有一个子表,它有一个主键和一个外键作为“ParentId”。因此,这两个表构成了单亲到多个子关系 问题是拉取父+子数据C代码的最有效方法是什么?必须将数据读入以下对象:C# 如何从SQL中读取父数据和子数据?,c#,asp.net,sql,sql-server-2008,ado.net,C#,Asp.net,Sql,Sql Server 2008,Ado.net,再次感谢您发布的所有精彩答案 我有两个SQL表。第一个定义父级,并有一个名为ParentId的主键列。我还有一个子表,它有一个主键和一个外键作为“ParentId”。因此,这两个表构成了单亲到多个子关系 问题是拉取父+子数据C代码的最有效方法是什么?必须将数据读入以下对象: public class Parent { public int ParentId { get; set; } public List<Child> Children { get; set; }
public class Parent
{
public int ParentId { get; set; }
public List<Child> Children { get; set; }
// ... many more properties ... //
}
public class Child
{
public int ChildId { get; set; }
public string Description { get; set; }
// ... many more properties ... //
}
使用这种方法,我必须找到所有唯一的父行,然后读取所有的子行。优点是我只去db一次
第二个版本是分别阅读所有家长:
SELECT * FROM Parents
SELECT * FROM Children
然后分别阅读所有儿童:
SELECT * FROM Parents
SELECT * FROM Children
并使用LINQ将所有家长与孩子合并。该方法可向db发送两次数据
第三种也是最后一种也是最低效的方法是抓取所有父对象,在构造每个父对象时,访问DB以抓取其所有子对象。这种方法需要n+1个连接:1个连接用于所有家长,n个访问次数用于获取每个家长的所有孩子
有没有关于如何更容易做到这一点的建议?当然,我不能不使用存储过程,也不能使用LINQ2SQL或EF。您更喜欢数据表还是数据读取器?如果是,如何使用方法1或方法2
谢谢,
马丁我通常在餐桌上做这个决定。有些桌子我经常需要孩子们,所以我马上就去拿。在其他情况下,访问孩子是很少见的,所以我懒得加载他们 我猜选项2在带宽方面比选项1更有效,因为您没有重复任何数据 您可以在一个存储过程中同时执行这两个查询,并使用sqldataadapter(即新的SqlDataAdaptercommand.FillmyDataSet)通过代码执行该过程,其中myDataSet将包含两个表 从这里,您可以阅读第一个表,通过ParentId在字典中创建父字典,然后只需阅读第二个表中的每一行即可添加子字典:
parents[(int)myDataSet.Tables[1]["ParentId"]].Children.Add(new Child() { etc } );
伪代码可能有点不对劲,但希望您能大致了解一下
使用这种方法,我必须找到
所有唯一的父行,然后
读所有的孩子
您可以通过p.ParentId包含订单。这确保来自同一父级的所有子级都在连续的行中。因此,您可以读取下一行,如果父对象已更改,则创建新的父对象,否则将子对象添加到上一个父对象。无需搜索唯一的父行。我更喜欢在一个查询中提取所有结果,只需在一个循环中构建树
SELECT p.ParentId as 'ParentId', null as 'ChildId'
FROM Parents p
UNION ALL
SELECT c.ParentId as 'ParentId', c.ChildId as 'ChildId'
FROM Children c
List<Parent> result = new List<Parent>();
Parent current;
while (dr.Read())
{
if (string.isNullOrEmpty(dr['ChildId']))
{
//create and initialize your parent object here and set to current
}
else if (!string.isNullOrEmpty(dr['ChildId'])
&& dr['ParentId'].ToString().Equals(current.ParentId.ToString())
{
//create and initialize child
//add child to parents child collection
}
}
我显然需要孩子们,这就是为什么我首先要问这个问题。