Linq到Datarow,选择多个列是不同的?

时间:2010-04-16 16:18:50

标签: vb.net linq

基本上我正在尝试将以下mssql查询重现为LINQ

SELECT DISTINCT [TABLENAME], [COLUMNNAME] FROM [DATATABLE]

我最接近的是

Dim query = (From row As DataRow In ds.Tables("DATATABLE").Rows _
                  Select row("COLUMNNAME") ,row("TABLENAME").Distinct

当我执行上述操作时,我收到错误

  

可以推断出范围变量名称   仅来自简单或合格的名称   没有争论。

我有点期待它返回一个我可以迭代并为每个条目执行操作的集合。 也许是数据集合?

作为一个完整的LINQ newb,我不确定我错过了什么。 我试过了

的变种
Select new with { row("COLUMNNAME") ,row("TABLENAME")}

并获得:

  

匿名类型成员名称即可   仅从简单或推断推断   没有参数的限定名称。

绕过这个我试过

 Dim query = From r In ds.Tables("DATATABLE").AsEnumerable _
        Select New String(1) {r("TABLENAME"), r("COLUMNNAME")} Distinct
然而,它似乎没有正确地做出独特的事情。

另外,有没有人知道任何好的书籍/资源能够流利?

4 个答案:

答案 0 :(得分:6)

您开始在数据表对象上使用LINQ,对dt.AsEnumberable运行查询,它返回一个IEnumerable DataRow对象集合。

Dim query = From row As DataRow In ds.Tables("DATATABLE").AsEnumerable _
              Select row("COLUMNNAME") ,row("TABLENAME")

您可能想说row("COLUMNNAME").ToString()等。查询将最终成为具有2个字符串属性的匿名类型的IEnumerable;是你所追求的? 可能需要指定属性的名称;我不认为编译器会推断它们。

Dim query = From row As DataRow In ds.Tables("DATATABLE").AsEnumerable _
              Select .ColumnName = row("COLUMNNAME"), .TableName = row("TABLENAME")

这假定在您使用ADO获取此数据集的原始SQL查询中,您确保结果是不同的。

混淆的常见原因:

一个关键是 Linq-to-SQL 和(通常称为 Linq-to-object 活动) LINQ-to-Dataset 是两件非常不同的事情。在两者中你都会看到LINQ被使用,所以它经常引起混淆。

LINQ到数据集

是:

1使用数据适配器和连接等获取数据表,使其与传统的数据表对象相同。然后,不像以前那样迭代行,而是:

2运行linq查询dt.AsEnumerable,这是一个IEnumerable数据行对象。

Linq-to-dataset选择( A NOT 使用Linq-to-SQL而是使用传统的ADO.NET,但随后( B )一旦拥有了数据表,就可以使用LINQ(-to-object)来检索/排列/过滤数据表中的数据,而不是我们6年来一直在使用它。我做了很多。我喜欢我的常规ado sql(使用我开发的工具),但 LINQ很棒

LINQ到SQL

是一种不同的野兽,在引擎盖下发生了截然不同的事情。在LINQ-To-SQL中,您:

1使用Visual Studio中的工具定义与您的数据库匹配的模式,该工具为您提供与模式匹配的简单实体对象。
 2您使用db Context 编写linq查询,并将这些实体作为结果返回。

在幕后,在运行时,.NET将这些LINQ查询转换为SQL并将它们发送到数据库,然后将数据转换为您在模式中定义的实体对象。

其他资源:

嗯,这是一个截然不同的摘要。要进一步了解这两个非常独立的事情,请查看:
   LINQ-to-SQL
   LINQ-to-Dataset

一本关于LINQ的精彩书是LINQ in Action,我的Fabrice Marguerie,Steve Eichert和Jim Wooley(曼宁)。去实现它(梦想);去得到它(东西!正是你所追求的。很好。 LINQ不是昙花一现,值得一本书。在.NET中,有很多东西需要学习,但掌握LINQ的时间花费的时间很长。

答案 1 :(得分:1)

我想我已经明白了。 谢谢你的帮助。

也许有一种更简单的方法呢?

我所做的是

Dim comp As StringArrayComparer = New StringArrayComparer
Dim query = (From r In ds.Tables("DATATABLE").AsEnumerable _
        Select New String(1) {r("TABLENAME"), r("COLUMNNAME")}).Distinct(comp)

这将返回一个运行自定义比较器的新字符串数组(2个元素)

Public Class StringArrayComparer
    Implements IEqualityComparer(Of String())

    Public Shadows Function Equals(ByVal x() As String, ByVal y() As String) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of String()).Equals

        Dim retVal As Boolean = True

        For i As Integer = 0 To x.Length - 1
            If x(i) = y(i) And retVal Then
                retVal = True

            Else
                retVal = False
            End If

        Next

        Return retVal

    End Function

    Public Shadows Function GetHashCode(ByVal obj() As String) As Integer Implements System.Collections.Generic.IEqualityComparer(Of String()).GetHashCode

    End Function
End Class

答案 2 :(得分:0)

查看linq to sql示例:

http://msdn.microsoft.com/en-us/vbasic/bb688085.aspx

学习SQL非常有用。如果您想练习,请使用LinqPad

HTH

答案 3 :(得分:0)

我有同样的问题,从各个方面我正在学习LINQ和IEnumerables,以下内容对我有用:

Dim query = (From row As DataRow In ds.Tables("DATATABLE").Rows _
              Select row!COLUMNNAME, row!TABLENAME).Distinct

奇怪地使用旧的VB bang(!)语法摆脱“范围变量名称...”错误但关键区别是使用{{1查询结果(IEnumerable)对象上的方法,而不是在查询中尝试使用.Distinct关键字。

然后,此LINQ查询返回一个IEnumerable集合anonymous type,其属性与DataRow中的选定列相匹配,因此可以访问以下代码:

Distinct

希望这有助于其他人绊倒这个问题......