基本上我正在尝试将以下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
然而,它似乎没有正确地做出独特的事情。
另外,有没有人知道任何好的书籍/资源能够流利?
答案 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被使用,所以它经常引起混淆。
是:
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-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
希望这有助于其他人绊倒这个问题......