【问题标题】:How to convert datatable record into child custom Class如何将数据表记录转换为子自定义类
【发布时间】:2015-07-23 10:33:54
【问题描述】:

我有两个班级,即:

public class Parent
{
    public int Id { get; set; }
    public int A { get; set; }
    public int B { get; set; }
}

public class Child : Parent
{
    public int C { get; set; }
    public int D { get; set; }
}

我有两个包含以下记录的数据表

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

显然必须将 ID 为 2 和 4 的父对象创建为子对象但是我不知道该怎么做。

请帮助我。 提前致谢。

【问题讨论】:

  • 数据表是否已经包含连接的结果,如果它有孩子,我们可以访问row.Field&lt;int&gt;("C"),或者孩子是否位于不同的数据表中?
  • 是的,孩子们位于不同的数据表中。

标签: c# .net linq list datatable


【解决方案1】:

你写道:

显然必须将 ID 为 2 和 4 的父对象创建为子对象

这不是很明显。根据您的布局,表 II 可能有两行具有相同的 ParentId,在您的示例中可能表示两个人住在一起,而属性 A 和 B 是地址和电话号码,而属性 C 和 D 可能表示生日和最喜欢的运动:两个住在一起的人住在一起的地址和电话号码相同,生日不同,喜欢的运动也不同。

如果您真的想在您的数据库中表达只有一个父 ID 为 2 的子节点和一个父 ID 为 4 的子节点,那么您的数据库将与第一个正常的数据库表单不匹配,并且不同的表布局会阻止两个人住在一起会更好。

话虽如此,我猜你想要以下内容:

从表 II 中的所有孩子创建一个列表,并将所有没有孩子的父母添加到表 II 中。子项的属性 A 和 B 应取自 Id 等于 ParentId 的表 I。

  • 用我的父母创建一个字典
  • 用 II 中的孩子创建一个序列,使用字典轻松找到属性 A 和 B 的值
  • 带走所有 I 中没有孩子的父母
  • 连接子级和最后一个父级列表

.

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

【讨论】:

    【解决方案2】:

    您可以创建一个函数来读取包含子对象信息的 DataTable(我在代码示例中将其称为 childDataTable)并创建 ParentChild 的实例:

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

    这将返回一个包含ParentChild 对象的混合列表

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 2012-02-08
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多