【问题标题】:Refactoring code with AsEnumerable使用 AsEnumerable 重构代码
【发布时间】:2017-12-22 19:49:35
【问题描述】:

我有以下代码:

var results = from table1 in ds.Tables[0].AsEnumerable()
join table2 in ds.Tables[1].AsEnumerable()
on table1["VendorNumber"] equals table2["VendorNumber"]
join table3 in ds.Tables[2].AsEnumerable()
on table1["VendorNumber"] equals table3["VendorNumber"]
select new
{ (select clause removed to save space here };

我试图将它重构为一个方法,但是当我这样做时,它给了我错误。重构方法的第一行是这样的:

private static IEnumerable<> Enumerable(DataSet ds)

我收到的错误是“意外使用未绑定的通用名称。”

关于我需要做什么才能正确将此代码重构为方法的任何建议?谢谢!

【问题讨论】:

  • 你必须给它一个具体的类型(你将从 LINQ 返回)。比如IEnumerable&lt;int&gt;IEnumerable&lt;double&gt;等。你现在有的是open type。
  • 首先,您缺少IEnumerable 的类型。
  • 您需要返回一个特定类型的IEnumerable,并且您必须指定它,但是由于当前基于您的选择语句,您正在返回一个匿名类型,您可以创建一个 DTO 类并返回它像这样stackoverflow.com/a/46905481/2946329

标签: c# console-application


【解决方案1】:

您似乎正在使用 ADO.NetDataSet 获取表格,并尝试使用 LINQ 将表格连接在一起。你不能那样做。 DataTable 中的每个DataRow 都应转换为与其包含的数据等效的对象。然后你可以加入对象。例如,如果DataTable 之一包含Foo 数据:

public class Foo
{
    public int FooId { get; }

    public int BarId { get; }

    public Foo(DataRow row)
    {
        FooId = row.Field<int>(nameof(FooId));
        BarId = row.Field<int>(nameof(BarId));
    }
}

而另一个DataTable 包含Bar 数据:

public class Bar
{
    public int BarId { get; }

    public Bar(DataRow row)
    {
        BarId = row.Field<int>(nameof(BarId));
    }
}

然后您将它们加入到匿名FooBar 对象的IEnumerable 中,如下所示:

var ds = new DataSet();

var foos = ds.Tables[0].Rows.OfType<DataRow>().Select(dr => new Foo(dr));
var bars = ds.Tables[1].Rows.OfType<DataRow>().Select(dr => new Bar(dr));

var foobars = from foo in foos
              join bar in bars
              on foo.BarId equals bar.BarId
              select new { Foo = foo, Bar = bar};

您可以改用ValueTuple

var foobars = from foo in foos
              join bar in bars
              on foo.BarId equals bar.BarId
              select (Foo: foo, Bar: bar);

顺便说一句,.Field&lt;T&gt; 扩展名在 System.Data.DataSetExtensions 中!

【讨论】:

    【解决方案2】:

    您需要指定集合元素的类型或使用类型参数

    private static IEnumerable<T> Enumerable(DataSet ds)
    {
        // function body here
    }
    

    在您的情况下,该函数返回DataRow 元素的集合(请参阅DataTableExtensions.AsEnumerable Method description)。所以,你可以使用

    private static IEnumerable<DataRow> Enumerable(DataSet ds)
    {
        // function body here
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 2014-04-11
      • 2016-02-09
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多