我有两个课程:
DataTable I (Parent Table)
ID A B
1 2 4
2 3 6
3 8 7
4 5 9
DataTable II (Child Table)
ParentID C D
2 4 10
4 9 7
我有两个带有以下记录的数据表
IList<Parent> items = dt.AsEnumerable().Select(row =>
new Parent
{
Id = row.Field<int>("Id"),
A = row.Field<int>("A"),
B = row.Field<int>("B"),
}).ToList();
如果我想将父数据表转换为父对象,请使用以下代码:
ProtocolCommands.h
显然,ID为2和4的父对象必须创建为子对象但是我不知道如何做到这一点。
请帮我解决这个问题。 提前谢谢。
答案 0 :(得分:2)
您写道:
显然,Id为2和4的父对象必须创建为子对象
这不是很明显。根据你的布局,表格II可以有两行具有相同的ParentId,在你的例子中可能意味着两个人住在一起,而财产A和B是地址和电话号码,而财产C和D可能意味着生日和最喜欢的运动:两个与同一地址和电话号码,不同的生日和不同喜欢的运动生活在一起的人们。
如果您真的想在数据库中表示只有一个父ID为2的子节点和一个父ID为4的子节点,那么您的数据库将与第一个普通数据库表单和不同的表格布局不匹配两个人住在一起会更好。
话虽如此,我想你想要以下内容:
从表II中的所有孩子创建一个列表,并在表II中添加所有没有孩子的父母。来自儿童的属性A和B应取自表I,其中Id等于ParentId。
var parentDictionary = AsEnumerable().ToDictionary(p => p.Id);
Ienumerable<Parent> children = II.asEnumerable()
.Where( c => parentDictionary.Keys.Contains(c.ParentId))
.Select(c => new Child()
{
A = parentDictionary[c.Id].A,
B = parentDictionary[c.Id].B,
C = c.C,
D = c.D
})
.Cast<Parent>();
IEnumerable<Parent> parentsWithoutChildren = I.AsEnumerable()
.Where(p => !II.AsEnumerable().Contains(p.Id));
IEnumerable<Parent> requestedPersons = parentsWithoutChildren
.Concat(children);
答案 1 :(得分:1)
您可以创建一个函数来读取保存子对象信息的DataTable(我在代码示例中称之为childDataTable
)并创建Parent
或Child
的实例和实例:
private Parent CreateObjectInstance(DataRow dataRow)
{
int parentId = dataRow.Field<int>("Id");
var childRow = childDataTable.AsEnumerable().SingleOrDefault(p => p.Field<int>("ParentID") == parentId);
if (childRow != null)
return new Child
{
Id = parentId ,
A = dataRow.Field<int>("A"),
B = dataRow.Field<int>("B"),
C = childRow.Field<int>("C"),
D = childRow.Field<int>("D")
};
else
return new Parent
{
Id = parentId ,
A = dataRow.Field<int>("A"),
B = dataRow.Field<int>("B")
};
}
然后,在您的LINQ语句中,只需在Select
方法中调用该函数:
var items = dt.AsEnumerable().Select(CreateObjectInstance).ToList();
这将返回一个包含Parent
和Child
个对象的混合列表