【问题标题】:Return type of Linq on Datatable数据表上 Linq 的返回类型
【发布时间】:2018-01-23 09:25:10
【问题描述】:

我有一个包含两列 ID 和角色的数据表。 同一个 ID 可以有多个角色。 我需要将此表转换为逗号分隔的分组表。 我正在尝试使用以下查询,但无法解决问题。

LINQ:

From row As DataRow In dtData.Rows.Cast(Of DataRow)
Group row By id = row.Field(Of Integer)("ID") Into Group
Select ID, Role = String.Join(",", From i In Group Select i.Field(Of String)("Role"))

问题

我们将不胜感激。

更新1:

表结构

需要的表结构

【问题讨论】:

  • 您的查询将返回您在Select 子句中指定的任何内容的通用IEnumerable。你没有在那里选择DataRows,所以你不会产生IEnumerable(Of DataRow)。不过,我真的不知道如何选择 DataRows,因为您正在尝试返回包含来自多个 DataRows 的数据的项目。
  • 谢谢@jmcilhinney 我正在检查接收对象数组的DataTable.LoadDataRow。我可以在 linq 中使用它来填充另一个 DataTable 并将 linq 的返回类型设置为对象吗?
  • 类似From row As DataRow In dtData.Rows.Cast(Of DataRow) Group row By id = row.Field(Of Integer)("ID") Into Group Select dtNew.LoadDataRow(New Object[] { ID, Role = String.Join(",", From i In Group Select i.Field(Of String)("Role")) }, False)

标签: vb.net linq uipath


【解决方案1】:

你可以在你的 cmets 中创建一个 linq,只是它返回一个字符串数组列表:

代码如下:

(From row As DataRow In myDatatable
Group row By id = row.Field(Of String)("ID") Into Group
Select {id, String.Join(",", From i In Group Select i.Field(Of String)("Role"))}).ToList

如果您需要数据表中的结果,您可以构建一个新的数据表

为每个结果创建一个并使用活动添加数据行。在 ArrayRow 中添加项目,在 DataTable 中添加新数据表

如果你使用活动输出数据表可以看到结果

【讨论】:

    【解决方案2】:

    我对您想要的最终结果感到困惑。一个可能会指导您但不是您想要的想法的想法是,您可以将 DataTable 更改为匿名投影,然后从中获得您想要的东西。您可以从 DataTable 中执行“选择”,该数据表进入您要选择的“什么”的扩展方法。如果我要在“新”之后执行一个没有任何类或容器对象的新 {},那么我的范围将仅限于一个方法。当您想通过一种方法为特定用途塑造某些东西以针对特定视图量身定制时,这是一个很好的优势。

    static void Main(string[] args)
    {
            DataTable d = new DataTable();
            d.Columns.Add("ItemName", typeof(string));
            d.Columns.Add("MinValue", typeof(float));
            d.Columns.Add("MaxValue", typeof(float));
    
            d.Rows.Add("Widget1", 0.1, 0.2);
            d.Rows.Add("Widget2", 0.2, 0.4);
            d.Rows.Add("Widget3", 0.1, 0.2);
    
            var dataTable = d.AsEnumerable();
    
            //What do you want to select?  The new {} without an indicator means anonymous type projection.  This will exist only in 
            // the scope listed.
            var data = dataTable.Select(x => new { ItemName = x[0], MinValue = x[1], MaxValue = x[2] }).ToList();
    
            //My 'data' type is now well typed for it's properties in the scope it's in.
            var joined = String.Join(", ", data.Select(x => x.ItemName).ToList());
    
            Console.WriteLine(joined);
            Console.WriteLine($"{data.Count}");
    
            Console.ReadLine();
    }
    

    编辑 1-26-18 奇怪我以为我昨天更新了代码。要获得可以将前端绑定到的可重用对象,您只需像这样创建一个 POCO:

     public class Foo
     {
         public string Bar { get; set; }
         public string MinAndMax { get; set; }
     }
    

    虽然您可以制作另一个 DataTable,但坦率地说,DataTable 就像 WinForms。他们完成了工作,但他们过时并且不友好地使用 Linq 就像一个结构良好的 POCO 一样容易。如果你开始使用 Linq,它会更好地处理格式良好的对象,并且它们很容易创建。

     var data = dataTable.Select(x => new Foo { Bar = x[0].ToString(), MinAndMax = $"{x[1]} {x[2]}" }).ToList();
    
     //My 'data' type is now well typed for 'Foo' class and it's properties in the scope it's in.
     var joined = String.Join(", ", data.Select(x => $"{x.Bar} {x.MinAndMax}").ToList());
    

    【讨论】:

    • 感谢 djangojazz 我已经更新了问题并添加了初始数据表和预期的结果数据表。 UiPath 不识别动态数据类型,所以我需要明确指定每个语句的返回类型。
    • 您可以添加一个特定的类来充当 POCO 并进行分配。我不知道你的数据,但基本上如果你必须连接多个字段,你可以这样做。
    猜你喜欢
    • 2012-12-13
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多