【问题标题】:Putting two Linq query data into two separate datatable columns将两个 Linq 查询数据放入两个单独的数据表列
【发布时间】:2014-05-21 13:25:15
【问题描述】:

我是 linq 的新手,在这个问题上被困了几天。下面是我的例子的xml。

                    <ItemGroupData ItemGroupOID="IG_TABLE_MODALITYTABLE" ItemGroupRepeatKey="1" TransactionType="Insert">
                        <ItemData ItemOID="I_TABLE_MODAL_DATE_TABLE" Value="2014-05-01" />
                        <ItemData ItemOID="I_TABLE_MODAL_TYPE_TABLE" Value="1" />
                    </ItemGroupData>
                    <ItemGroupData ItemGroupOID="IG_TABLE_MODALITYTABLE" ItemGroupRepeatKey="2" TransactionType="Insert">
                        <ItemData ItemOID="I_TABLE_MODAL_DATE_TABLE" Value="2014-05-02" />
                        <ItemData ItemOID="I_TABLE_MODAL_TYPE_TABLE" Value="2" />
                    </ItemGroupData>

我想要实现的是将 ItemData 区分为 DATE 和 TYPE,然后将其放入已创建的数据表列中。下面是我目前的尝试,它只连接行而不是将数据放入两个创建的列中。非常感谢你的帮助。任何意见是极大的赞赏。干杯。

            DataTable modDt = new DataTable();
            modDt.Columns.Add(new DataColumn("Date", typeof(string)));
            modDt.Columns.Add(new DataColumn("Type", typeof(string))); //changed to string?

            var document = XDocument.Load("doc.xml");

            XNamespace nsSys = "http://www.cdisc.org/ns/odm/v1.3";

             //Get nodes separated by inner child element
             var values = document.Descendants(nsSys + "ItemData")
            .Where(t => t.Attribute("ItemOID").Value == "I_TABLE_MODAL_DATE_TABLE")
            .Select(x => x.Attribute("Value").Value);

             foreach (var item in values)
             {
                 modDt.Rows.Add(DateTime.ParseExact(item, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("MM/dd/yy"),null);
             }


             var typevalues = document.Descendants(nsSys + "ItemData")
             .Where(t => t.Attribute("ItemOID").Value == "I_TABLE_MODAL_TYPE_TABLE")
             .Select(x => x.Attribute("Value").Value);

             foreach (var item in typevalues)
             {
                 modDt.Rows.Add(null ,int.Parse(item));
             }

             foreach (DataRow row in modDt.Rows)
             {
                 string sessionDate = row["Date"].ToString();
                 string mod = row["Type"].ToString();

                 string xnatCli = mod + sessionDate;
                 Console.Write(xnatCli);
             }

             Console.Read();

【问题讨论】:

    标签: c# linq datatable multiple-columns


    【解决方案1】:

    您的代码中有一些假设,即 I_TABLE_MODAL_DATE_TABLE 和 I_TABLE_MODAL_TYPE_TABLE 将始终匹配。我发布的代码进行了额外检查,以确保这是一个正确的假设。还将它们分组,以便我们为每个有效的 ItemGroupData 获得一行。如果缺少其中一个属性,则只需添加有效的属性,如果两者都丢失,则跳过该行。此外,如果有多个具有相同名称的属性,则代码仅采用 ItemGroupData 中的最后一个。

    var modDt = new DataTable();
    modDt.Columns.Add(new DataColumn("Date", typeof(DateTime)));
    modDt.Columns.Add(new DataColumn("Type", typeof(int))); 
    
    var document = XDocument.Load("doc.xml");
    
    XNamespace nsSys = "http://www.cdisc.org/ns/odm/v1.3";
    
    //Get ItemData attributes group by the itemGroupData
    var itemGroupDatas =
        document.Descendants(XName.Get("ItemGroupData", nsSys.NamespaceName))
                .Elements(XName.Get("ItemData", nsSys.NamespaceName))
                .Select(x => new
                    {
                        itemOID = x.Attribute(XName.Get("ItemOID")),
                        value = x.Attribute(XName.Get("Value"))
                    })
    
                .Where(
                    x =>
                    x.itemOID != null && x.value != null &&
                    (x.itemOID.Value == "I_TABLE_MODAL_DATE_TABLE" ||
                     x.itemOID.Value == "I_TABLE_MODAL_TYPE_TABLE"))
                .GroupBy(x => x.itemOID.Parent.Parent, x => x);
    
    foreach (var itemGroupData in itemGroupDatas)
    {
        // record per each group
        var row = modDt.NewRow();
        foreach (var itemData in itemGroupData)
        {
            if (itemData.itemOID.Value == "I_TABLE_MODAL_DATE_TABLE")
            {
                DateTime date;
                if (DateTime.TryParse(itemData.value.Value, out date))
                {
                    row["Date"] = date;
                }
            }
            if (itemData.itemOID.Value == "I_TABLE_MODAL_TYPE_TABLE")
            {
                int type;
                if (int.TryParse(itemData.value.Value, out type))
                {
                    row["Type"] = type;
                }
            }
        }
        modDt.Rows.Add(row);
    }
    Console.ReadLine();
    

    【讨论】:

    • 为您的解决方案干杯。这是一个很好的解决方案。然而,我得到的日期略有偏差。它给了我。 2014 年 1 月 5 日 00:00:00 和 2014 年 2 月 5 日 00:00:00。我想得到 05/01/14 和 02/05/14。干杯。
    • C# 不仅有 Date 类型。它总是日期时间。如果您只想要日期部分,您可以通过执行 date.ToShortDateString() 将其转换为字符串。
    猜你喜欢
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2016-02-03
    相关资源
    最近更新 更多