VB.NET中LINQ TO List泛型查询语句(分组,聚合函数)

print?Public Class LinqToList 
   
‘LINQ在C#中选取相比便于,但是在VB中运用比较费心,复杂,和C#用法并不太一致  
    Dim listNew As List(Of Product) = New List(Of Product)  ‘新商品  
    Dim listOld As List(Of Product) = New List(Of Product)  ‘旧商品  
 
    ‘****** 给 listNew 加载数据 此处省略******  
    ‘****** 给 listOld 加载数据 此处省略******  
 
    ‘查询 listNew 中的最高价 price1,并按
price,name,unit,model,node分组  
    Dim temp = From Item In listNew 
                    Group Item By Key = New With {Key Item.Name, Key
Item.Unit, Key Item.Model} 
                    Into g = Group Select New With {.price1 = (Aggregate
p In g Into Average(p.Price)), 
                                                    .price = (From p In
g Select p.Price), 
                                                    .name = Key.Name, 
                                                    .unit = Key.Unit, 
                                                    .model =
Key.Model, 
                                                    .note = (From p In g
Select p.Note)}    ‘note并未有在分组中,不可能再key中获得  
 
    ‘合併listNew 和listOld ,并按
price,name,unit,model,node分组,求出合併后的最高价price1,同样产品的个数.count  
    Dim tempMax = From Item In 
            ((From Contact In listNew).Union(From Shipment In
listOld)) 
            Group Item By Key = New With {Key Item.Name, Key Item.Unit,
Key Item.Model} 
            Into g = Group Select New With {.price1 = (Aggregate p In g
Into Max(p.Price)), 
                                            .price = (From p In g Select
p.Price), 
                                            .name = Key.Name, 
                                            .unit = Key.Unit, 
                                            .model = Key.Model, 
                                            .note = (From p In g Select
p.Note), 
                                            .count = g.Count()} 
 
    ‘最低价 .price1 = (Aggregate p In g Into Max(p.Price)) 改成 .price1
= (Aggregate p In g Into Min(p.Price))   
    ‘平均价 .price1 = (Aggregate p In g Into Max(p.Price)) 改成 .price1
= (Aggregate p In g Into Average(p.Price))  
End Class 
 
Public Class Product 
    Private mPrice As Double     ‘价格  
    Private mName As String      ‘名称  
    Private mUnit As String      ‘单位  
    Private mModel As String     ‘规格  
    Private mNote As String      ‘备注  
    Public Property Price() As Double   ‘价格  
        Get 
            Return mPrice 
        End Get 
        Set(ByVal value As Double) 
            mPrice = value 
        End Set 
    End Property 
 
    Public Property Name() As String    ‘名称  
        Get 
            Return mName 
        End Get 
        Set(ByVal value As String) 
            mName = value 
        End Set 
    End Property 
 
    Public Property Unit() As String    ‘单位  
        Get 
            Return mUnit 
        End Get 
        Set(ByVal value As String) 
            mUnit = value 
        End Set 
    End Property 
 
    Public Property Model() As String   ‘规格  
        Get 
            Return mModel 
        End Get 
        Set(ByVal value As String) 
            mModel = value 
        End Set 
    End Property 
 
    Public Property Note() As String    ‘备注  
        Get 
            Return mNote 
        End Get 
        Set(ByVal value As String) 
            mNote = value 
        End Set 
    End Property 
End Class 

使LINQ可行的VB9.0语言特征

商厦须要自家做 Silver Light rearch   

Class LinqToList
LINQ在C#中使用相比便于,可是在VB中应用比较费心,复杂,和C#用法并不太一样Dim listNew As List(Of Product) = New List(Of P…

品类推测(自动类型设定)

花色揣测三翻五次了VB的观念意识,为静态变量在可能的处境下、为动态变量在须求的时候测度类型。在VB9里面,编译器没有要求为有着的数量显式的扬言类型,而是定义变量的同不平时候,通过其开头化的表达式来推论变量的档期的顺序。举个例子下边包车型地铁代码:

Dim
population = 131000

Dim name = “Springfield”

Dim area = 1.9

Dim someNumbers = {4, 18, 11, 9, 8, 0, 5}

For Dim i = 0 To 10

    
Console.WriteLine(i)

Next

将鼠标移动到变量上边,你会看出这么些变量的项目已经被估摸成你所想要的品种了。

Dim population As Integer = 131000
Dim name As String = “Springfield”
Dim area As Double = 1.9 
Dim someNumbers() As Integer = {4, 18, 11, 9, 8, 0, 5}

For i As Integer = 0 To 10
    Console.WriteLine(i)
Next

当心,类型推侧实在编写翻译时成功的,并非选用最2020时代绑定。

你可以看来在此文的后续部分,通过项目推侧你可以不用评释类型而直白定义查询再次来到值。

(译注)

能够接纳二个常量进行项目揣摸,比方

        Dim aInt =
5              ‘Integer

        Dim
aDbl = 1.2            ‘Double

        Dim
aStr = “farrio”       ‘String

        Dim
aChr = “A”c           ‘Char

也能够证明数组

        Dim aArr1() = {1, 2, 3, 4,
5}

        Dim aArr2() = {“1″, ” 2″, “3”,
” 4″, ” 5″}

数组纵然不是多少个项目标话,将会尽大概的无损转化为恐怕的体系。

        Dim aArr3() = {1, 2, 3, 5, 5,
6.2}     
‘Double()

而是借使数组的初步化部分不可能自动转化成三个品类的时候,将会自动测算为她们的基类。

    Dim
aArr3() = {1, “2”, 3, “5”, 5, 6.2}    
‘Object()

动态推断只匡助部分变量,而不支持成员变量。

    Private a
= 123       ‘Runtime:
Int32 Compile-Time:
Object

发觉silver light 数据绑定多少有一些优伤    object datasource  要等到 
vs二〇〇八   

佚名类型

VB9能够活动测算已定义的连串变量(如前例所示)。并且,他仍是能够够创制一个并未被声称过的门类的实例。因为那个新的门类一贯都未曾被声称过,所以是“佚名类型”。

无名类型营造在另一个VB9的新特色的底子之上——对象开始化器。使用对象起先化器,你能够行使一些表明式来初阶化三个繁杂的对象实例。举例,假如您看了Visual Basic 9 Survey工程里面Object Initializers这一部分的原委,你能够看到二个名称叫Customer的类定义,包含Name、Address和City属性。你能够用成千上万艺术来初叶化这些类的实例。举个例子说,你能够全部地钦命这几个指标的类型以及具备成员的值。

Dim
cust1 As Customer = New Customer {Name := “Nancy”, _

    Address := “

123 Main St.

“, City := “Louisville”}

看似的,你也足以只开端化一部分成员而别的成员运用其私下认可值。

也能够在等号的右面省略掉类型来让编写翻译器自动测算那几个类型。

Dim
cust1 As Customer = {Name := “Nancy”, Address := “

123 Main St.

“, City := “Louisville”}

抑或您也得以省略掉等号侧边的证明类型。

Dim
cust1 = New Customer {Name := “Nancy”, Address := “

123 Main St.

“, City := “Louisville”}

对象初步化器和无名类型结合在协同,在后面包车型地铁一些将会看到使用到查询工程的例证。再举三个简易的事例,若是您想创设贰个Product类包涵二个Name和五个Price属性,你能够定义多个包蕴Name和Price成员的Product类,然后像前面Customer的特别例子那样实例化,也许您也得以这么:

Dim
someProduct = New {Name := “paperclips”, _
     Price := 1.29}

要去印证一下编写翻译器确实是依据你的必要树立了贰个暗含四个分子的实例,输入

Console.WriteLine(someProduct.

使用智能感知工夫体现所含有的三个属性(你能够看出Name和Price)。若是你将鼠标悬停在someProduct变量上边,你能够看来她被定义为了一个无名类型的实例。何况Name和Price分别被定为String和Double类型。变量someProduct是多个强类型对象,在编写翻译时就曾经分明了种类和分子,只可是编写翻译器是通过她的开始化部分来确立的。

在3.7和3.8节里面,描述基于LINQ的询问表明式结构的时候还是可以看出那部分的开始和结果。私下认可类型允许你从原始类型会集中开创三个富含部分成员(并非整整分子)的新类型集合,大概将两个集聚合併在一块。使用投影,你能够挑选输入数据中所关切的一对,何况让VB将他们包裹在三个类里面。

(译注)

无名类型优先于对象起先化器。比方贰个Person类,满含Name和Age属性。要是大家定义

        Dim p = New {Name := “xuzy”,
Age := 27}

那正是说得到的不是全自动估测计算的Person对象,而是多个无名氏对象。

唯有我们在等号的一方出席Person注解(左右任何一方均可)就足以活动测算出Person实例了。

别的,相同成员的无名氏类型是一律的,比方

        Dim p1 = New {Name := “xuzy”,
Age := 27}

        Dim p2 = New {Name := “yinxb”, Age
:= 25}

她俩是同贰个类型的。p2 = p1操作是能够的。

无名类型也仅支持部分变量,假如是多少个分子变量,比如

    Private
b = New {Name := “xuzy”, Age := 27}

在运作时是叁个无名氏类型,不过编写翻译时是Object对象。就算能够通过

       
Console.WriteLine(b.Name)

来博取成员,可是那时最终时代绑定了。

 

于是乎自身写了二个 

LINQ查询表明式

 

查询表明式的语法

先是看七个询问整形数组的事例,来探访VB9的查询。

那是数组

Dim
someNumbers = {4, 18, 11, 9, 8, 0, 13, 21, 5}

这是询问语句

Dim
oneDigitNumbers = From n In someNumbers _
     Where n < 10 _
     Select n

那是结果

Console.WriteLine(“One-digit
numbers from the list:”)
For Each Dim m In oneDigitNumbers
     Console.Write(m & ” “)
Next

只顾在证明someNumber以及oneDigitNumbers的时候使用的类型估算。

正如你所见到的,二个为主的询问表明式由From…Where…Select组成。要是你将鼠标悬停在变量上面,你能够看出在查询语句中,n被定义为Integer,oneDigitNumbers是IEnumerable(Of
Integer)类型——基本上是三个数组集合。

正如上边包车型地铁例子所示,For…Each…Next方法能够很便利的遍历(迭代)查询表明式的结果集结中(只怕具有实现了IEnumerable接口的集聚对象)的每贰个要素。

(译注)

LINQ的询问语句和SQL有所不用。

率先是From语句,他定义了查询的目标集合而且推测出每叁个询问成分的档案的次序。

From
n In someNumbers

那边someNumbers是查询的对象集结,由于是Integer数组,所以n被猜想为Integer类型。

附带是Where子句,由于From子句里面早就宣示了n,所以那边就能够使用了。

末了是Select子句,表示要重临的品类。我们得以这样

Select
New {BaseValue := n, DoubleValue := n * 2}

全数的查询表明式重返值都以IEnumerable接口实例,只可是依照Select子句的两样,他的范型类型差别而起。使用动态推测就能够节省顾客判定再次来到值类型的分神而平素询问结果。所以查询表明式重回值对于使用者来讲是透明的,大家得以不用去关怀它。

用取得的自然会看懂   哼哼

用Order By排序

想要为结果排序,在Select子句前边使用Order
By。

‘From
… Select … Order By …

Dim
inOrder = From n In someNumbers _
     Select n _
     Order By n

‘From
… Where … Select … Order By …

Dim
oneDigitNumbersInOrder = From n In someNumbers _
     Where n < 10 _
     Select n _
     Order By n

Order By暗中认可使用降序排序。你也得以选用Ascending和Descending关键字来特意指明升序依旧降序。

Order
By n Ascending

Order
By n Descending

(译注)

Order By字句里面推行排序的字段只可以是出现在Select里面包车型大巴字段,或许是Select里面字段的一点成员(属性、方法等)。那点和C# LINQ不太同样。比如

        Dim oneDigitNumbers = From n In
someNumbers _

            Where n < 10 _

            Select n _

            Order By n

唯独如果大家这么写

        Dim oneDigitNumbers = From n In
someNumbers _

            Where n < 10 _

            Select n.ToString _

            Order By n

就能够出错,编写翻译器提醒“n未有定义”。不清楚那是或不是VB LINQ的一个BUG。

唯独一旦

        Dim oneDigitNumbers = From n In
someNumbers _

            Where n < 10 _

            Select n _

            Order By n.ToString

是从未难点的。

 

协调操作符

针对数值的情商操作符引进LINQ中,上面包车型客车事例中应用Count方法来做个例证。合计操作符作用于二个会师,将每八个元素合併到三个值中,比方为集聚的数码举办协商、计数操作。

Dim
oneDigitCount = Count(From n In someNumbers _
     Where n < 10 _
     Select n)

或者

Dim
oneDigCt = (From n In someNumbers _
     Where n < 10 _
     Select n).Count()

Console.WriteLine(“Number
of one-digit numbers: ” & _
     oneDigitCount)

别的的磋商操作符有Min、Max、Sum和Dellage,使用情势和Count同样。请参见追加实例Sample Queries project,101 LINQ
Query 萨姆ples和Aggregate Operators。

(译注)

实质上合计操作符是概念在System.Query.Sequence类里面包车型地铁一文山会海静态方法。

经过“扩充方法”的方式将其扩充到具有IEnumerable接口的实例上。大家得以平昔行使那一个静态方法,也得以运用IEnumerable的恢弘方法。

 

细分操作符

划分操作符允许你从询问重回集结中只收取一有的,或然除了有个别部分之外的子集。

动用Take(i)可以回到查询结果中的前i个记录。(类似于SQL里面包车型地铁TOP关键字)

Dim
takeFive = (From n In someNumbers _
    Select n).Take(5)

采取Skip(i)能够回到查询结果集结中前i项以外的数据。

Dim
skipFive = (From n In someNumbers _
    Select n _
    Order By n).Skip(5)

 

点名成分操作符

应用钦定成分操作符,能够从询问结果中甄选一个特定的成分。

First操作符重返结果中的第贰个成分。

Dim
firstElement = (From n In someNumbers _
    Where n > 20 _
    Select n).First()

ElementAt(i)方法重返结果中的第i个因素。由于结果会集的下标从0开首,所以上边包车型大巴例子里面再次回到的是第多个成分。

Dim
fourthElement = (From n In someNumbers _
    Select n _
    Order By
n).ElementAt(3)

(译注)

要潜心,内定成分操作符将会回去所迭代的类型并非IEnumerable对象。

同不平日候,要是回去的会集为空集(未有成分),那么使用First方法将会吸引二个名字为ArgumentInvalidateException的特别。

一旦ElementAt的参数超过了聚众的最大下标,将会再次来到OutOfRangeException。

 

采取结构化数据的事例

上边包车型客车事例是用了三个小的Customer实例的聚众,这些实例的概念能够在Visual Basic 9 Survey project里面找到。

每三个Customer对象蕴涵八个Name,二个Address(街道地址)和多个City属性。还应该有三个可见回来当前开销者列表的秘籍GetCustomers,三个子程序ObjectInitializers用来树立和具体那一个列表。

那些事例的操作和3.1-3,5节看似,可是操作的对象会集不是整形了。

首先,壹个From…Where…Select的例子。查询全数地点里面包括“123”的客户。


Here is the customer list
Dim customers = GetCustomers()


Here is the query
Dim custs = From cust In customers _
     Where
cust.Address.Contains(“123”) _
     Select cust


Here is the result — display their names
Console.WriteLine(“Customers with 123 in their addresses:”)
For Each Dim c In custs
     Console.WriteLine(”  Name: ” & c.Name)
Next

再也注意,编写翻译器精确的猜测了customers、custs和c的品种。你能够选择智能感知去验证他们的档案的次序。

刚才的事例是用了三个间接的阴影操作,采取符合要求的要素况且重临。同样的,也足以写一个单值投影来回到贰个缩短的对象,从原本的多少中只取得唯一的多少个分子。上面包车型客车例证只回去了符合须求的成分的Name属性。

Dim
custNames = From cust In customers _
     Where
cust.Address.Contains(“123”) _
     Select cust.Name

Console.WriteLine(“Customers
with 123 in their addresses:”)
For Each Dim cname In custNames
     Console.WriteLine(”  Name: ” & cname)
Next

假设你将鼠标悬停在cname变量下边,你能够看来他被估计为String类型。你也能够看看custs和custNames的品种。

参照他事他说加以考察3.7节多值投影的事例。

行使Order By能够特别简单进行排序。上面包车型客车查询语句用Name的值举行排序。

Dim
custsInOrder = From cust In customers _
     Where
cust.Address.Contains(“123”) _
     Select cust _
     Order By cust.Name

Console.WriteLine(“Customers
with 123 addresses, in order:”)
For Each Dim c In custsInOrder
     Console.WriteLine(“Name: ” &
c.Name)
Next

您也能够利用接二连三的值举行排序。试试这几个,先用City排序再用Name排序。

(注意,无法对Select以外的对象作为排序的字段。也便是说,我们当下还不能够投影cust.Name,并且用cust.City排序。)

Dim
custsInOrder = From cust In customers _
     Select cust _
     Order By
cust.City,cust.Name

上边例子里面包车型地铁商事操作符和省略多少的运用方法、试行结果一样。当然你首先要调整如何对象要被比较、合计可能平均。

Dim
firstCity = (From cust In customers _
     Select cust.City).Min()
‘ or alternatively
‘Dim firstCity = Min (From cust In customers _
‘ Select cust.City)

Console.WriteLine
(“The first city, alphabetically, is ” & _
     firstCity)

上边包车型客车那几个事例获得了City属性集结並且取中间的首先个值。

Dim
startCity = (From cust In customers _
    Select
cust.City).First()

以那件事例取得除了第多少个值以外的其余值。

Dim
allButFirst = (From cust In customers _
    Select
cust.City).Skip(1)

最后,这一个例子用了ElementAt取重返集结中的第三个要素。

Dim
secondCity = (From cust In customers _
    Select
cust.City).ElementAt(1)

图片 1图片 2Code
Public Enum rowStatus
    UnChanged = 0
    Inserted = 1
    Updated = 2
    Deleted = 3
End Enum

运用佚名类型实行多值投影

佚名类型能够用来从现存项目实行多值投影操作(参照3.6节的单值投影,以及2.2节的佚名类型介绍)。比如,在Visual Basic 9
Survey例子工程里面,你可能希望从Customer类里面获取一个暗含街道地址和城市的实例列表,不过不分包Name音讯。使用无名类型你能够有比比较多的渠道来实现。

营造二个附带名字的佚名类型。(为Customer里面的Address和City在无名氏类型里面创立多个新的习性名字)

Dim
customerLocs = From cust In customers _

     Select New {theStreet :=
cust.Address, theCity := cust.City}

将设定值所属的品质作为佚名类的的性质。(参见3.8节)

Dim
customerLocs = From cust In customers _
     Select New {cust.Address,
cust.City}

最终,用叁个简易的询问表明式完毕。

Dim
customerLocs = From cust In customers _
     Select cust.Address,
cust.City

下边的例子里面,想要展现在customerLocs列表里面cLoc.Name属性将会抓住错误,因为那一个成员已经不属于重回的要素的。不过cLoc.Address和cLoc.City仍旧有效。

Console.WriteLine(“City
names in customerLocs: “)
For Each Dim cLoc In customerLocs
    
‘Console.WriteLine(cLoc.Name)
     Console.WriteLine(”  ” & cLoc.City)
Next

下边包车型客车事例更能展现这一特点,一个询问系统当下经过的程序。System.Diagnostics.Process类里面好些个的公家属性,大概你只关怀ProcessName和ID那五个新闻。要是是那样,你就足以创立二个只含有着四个分子的新集合。

Dim
tasks = From proc In _
  
System.Diagnostics.Process.GetProcesses() _
     Where proc.Threads.Count
> 10 _
     Select proc.ProcessName,
proc.ID

Console.WriteLine(“Processes:”)
For Each Dim task In tasks
     Console.WriteLine(”  Name : ” & task.ProcessName & _
        ” ID: ” & task.ID)
Next

采纳只可以感知去检验Task.ProcessName,他是八个String类型属性,ID则是Integer类型,况兼Task是一个无名类型。这么些例子还优秀了二个新的新闻:你能够查询全数的集聚类型。GetProcesses方法再次回到多个进程集合对象,你能够想询问任何其余集合对象同样查询他。

(译注)

如前所述,Order By子句只好查询Select子句里面的连串,如若Select子句是八个无名氏类型,那么大家将不可能举行Order
By操作。不过在C# 3.0里面是能够的。

动用it关键字(参见3.9节)能够化解那么些题目。It关键字表示此番询问操作的迭代器对象,也正是大家最终要回去的结果集结的成员类型。举例

        Dim ps = From p In persions
_

            Select p.Name, p.Age
_

            Order By it.Age Descending,
it.Name Ascending

这里的it便是Select子句重返的无名类型。

Public Class DataTableFake(Of T As ComponentModel.INotifyPropertyChanged)
    Implements Collections.Generic.IList(Of T)
    Implements System.ComponentModel.INotifyPropertyChanged

从多个数据源结合数据

您可以选用LINQ查询表明式方便的将多个数据源的数码整合在一块,运用起来就和从单纯数据源取得数据一致的轻巧。下边包车型客车例子将具备customers数据之中,地址新闻富含在一个oneDigitNumbers数组(在3.1节里边创立的)里面包车型客车成员收取来。

Dim
custsWMatchingDigit = From cust In customers, n In oneDigitNumbers _
    Where
cust.Address.Contains(n.ToString()) _
    Select cust

Console.WriteLine(“Customers
with digit match in their addresses:”)
For Each Dim c In custsWMatchingDigit
    Console.WriteLine(”  ” & c.Name)
Next

你也得以平价的再再次回到音信里面到场另三个数据源的开始和结果。

Dim
custsWMatchingDigit = From cust In customers, n In oneDigitNumbers _
    Where
cust.Address.Contains(n.ToString()) _
    Select cust,n

Console.WriteLine(“Customers
with digit match in their addresses:”)
For Each Dim custn In custsWMatchingDigit
    Console.WriteLine(”  ” & custn.cust.Name & “, ” &
custn.n)
Next

留神,Name属性在七个显示操作里面包车型大巴代码是差别的,因为custsWMatchingDigit成员在五个例证里面是多个差别的结构。第一个例证重返的是customer的集合,饱含Address和City属性,然则第三个例子里面,重回的却是一个包涵了cust和n属性的无名氏类型。

再上二个例子里面,oneDigitNumbers和customers都完毕了IEnumerable接口,但那并不是必不可缺的。假诺您用someNumbers,二个整数数组来替换oneDigitNumbers,程序还是能够够健康运作。

在Form子句里面有二个活动的迭代顺序。上三个例子是经过三个数值列表内的值来对customer的地方音信实行查找。上边包车型地铁事例,通过装有的customer的地址和整数列表举行寻找。即便取得结果列表的积极分子是一模一样的,然而各样却是不雷同的。

Dim
digitsWMatchingCusts = From n In oneDigitNumbers, cust In customers _
    Where
cust.Address.Contains(n.ToString()) _
    Select cust

Console.WriteLine(“With
the iterator for digits first:”)
For Each Dim c In digitsWMatchingCusts
    Console.WriteLine(”  ” & c.Name)
Next

(译注)

动用方面包车型地铁搜寻,将会爆发笛Carl乘积。一样的门类将会再也出现。比方在number数组里面有1,2,3那多少个分子,在customer的address中有多少个address同一时候含有了1,2,3,那么将会在结果集结中回到多少个那一个customer对象。

不过采用上面包车型地铁艺术可防止止这几个现象。

第一思量这么多少个类,Person和Department。

Public
Class Department

    Private m_dCode As String

    Private m_dName As String

    Public Property Code() As
String

        Get

            Return Me.m_dCode

        End Get

        Set(ByVal value As
String)

            Me.m_dCode = value

        End Set

    End Property

    Public Property Name() As
String

        Get

            Return Me.m_dName

        End Get

        Set(ByVal value As
String)

            Me.m_dName = value

        End Set

    End Property

End
Class

 

Public
Class Person

    Private m_Name As String

    Private m_Age As Integer

    Private m_Department As
String

    Public Property Department() As
String

        Get

            Return
Me.m_Department

        End Get

        Set(ByVal value As
String)

            Me.m_Department =
value

        End Set

    End Property

    Public Property Name() As
String

        Get

            Return Me.m_Name

        End Get

        Set(ByVal value As
String)

            Me.m_Name = value

        End Set

    End Property

    Public Property Age() As
Integer

        Get

            Return Me.m_Age

        End Get

        Set(ByVal value As
Integer)

            Me.m_Age = value

        End Set

    End Property

    Public Overrides Function
ToString() As String

        Return String.Format(“Name:
{0}{1}Age: {2}{1}Department: {3}”, Me.m_Name, vbTab, Me.m_Age,
Me.m_Department)

    End Function

End
Class

以及她们获得数组的点子

Function
GetPersonList() As Person()

    Return New Person() { _

    New Person {Name := “xuzy”, Age :=
27, Department := “1”}, _

    New Person {Name := “zhangkun”, Age
:= 24, Department := “QA”}, _

    New Person {Name := “yinxb”, Age :=
25, Department := “1”}, _

    New Person {Name := “Diablo”, Age
:= 30, Department := “1”}, _

    New Person {Name := “hehui”, Age :=
26, Department := “1”}, _

    New Person {Name := “Happy2007”,
Age := 29, Department := “3”}, _

    New Person {Name := “loulou”, Age
:= 29, Department := “1”}, _

    New Person {Name := “pangzi”, Age
:= 29, Department := “1”}}

End
Function

 

Function
GetDepartmentList() As Department()

    Return New Department() { _

    New Department {Code := “1”, Name
:= “1部”},
_

    New Department {Code := “2”, Name
:= “2部”},
_

    New Department {Code := “3”, Name
:= “3部”},
_

    New Department {Code := “QA”, Name
:= “QA部”}}

End
Function

其实的操作如下

    Dim persions =
GetPersonList()

    Dim dps =
GetDepartmentList()

    Dim ps = From d In dps, p In
persions _

        Where p.Department = d.Code
_

        Select New {Person := p.Name,
Age := p.Age, Code := p.Department, Dp := d.Name}

    For Each p In ps

       
Console.WriteLine(p.ToString)

    Next

实在是一个左右连接的例证,通过Where
p.Department = d.Code连接三个数据源,假诺不相配则不出口。这样就解除了笛卡儿积。

    Implements System.Collections.Specialized.INotifyCollectionChanged
    Private CoreDictionary As New Collections.Generic.Dictionary(Of T, rowStatus)
    Private CoreList As New Collections.Generic.List(Of T)

分组操作

Gourp By允许你选用某八个标准对输入群集的因素举办分组,况兼同意你拜候每三个子组。以后的Group By使用三个代表迭代器变量的上下文关键字it。由Groupt By子句,it关键字表示查询结果会集中的迭代成分。举个例子,下边包车型大巴询问将someNumbers数组分组为奇数和偶数,並且为每二个组记数。

Dim
oddEven = From n In someNumbers _
     Group By n Mod 2 _
     Select it.Key,
Count(it)

Console.WriteLine(“Count
of even and odd integers in someNumbers:”)
For Each Dim g In oddEven
     Console.WriteLine(“Key: ” &
g.Key & ” Count: ” & g.Count)
Next
Console.WriteLine()

显示的结果如下:

Key:
0  Count: 4

Key:
1  Count: 5

Key项目也足以不是数字。上面包车型客车事例将customers依照city进行分组。Key是City名字。(字符串)

Dim
cityCount = From cust In customers _
    Group By cust.City _
    Select it.Key,
Count(it)

Console.WriteLine(“Number
of times each city occurs in customers:”)
For Each Dim ct in cityCount
    Console.WriteLine(ct.Key & “,
” & ct.Count)
Next
Console.WriteLine()

瞩目,输出分组音讯的cities的各类和输入顺序保持一致。假设您想排序,能够在询问表明式的末尾使用Order By子句。

Dim
cityCount = From cust In customers _
    Group By cust.City _
    Select it.Key, Count(it) _
    Order By it.Key

分组Key也足以是贰个佚名类型。上边包车型客车例证扩大了3.8节的事例,从customer里面选拔address属性中包蕴oneDigitNumbers整形数组成分,使用二个包罗了City和Name属性的无名类型来分组,最后将每一组里面有稍许成员举行投影。

Dim
grp = From c In customers, n In oneDigitNumbers _
    Where
c.Address.Contains(n.ToString()) _
    Group By New {c.City, c.Name}
_
    Select it.key, Count(it)
    Order By it.key.City

Console.WriteLine(“Results
with anonymous type:”)
For Each Dim g In grp
    Console.WriteLine(”  Key: {0}, Occurrences: {1}”, g.key,
g.Count)
Next

(译注)

实际上,满含了Group By子句的查询表达式的重临值是一个IGrouping接口的实例,况且它还达成了IEnumerable接口。怀念上面包车型地铁代码

        Dim nums = {1, 2, 3, 4, 5, 6,
7, 8, 9, 10}

        Dim odd = From n In nums
_

            Group By n Mod 2 _

            Select it

在此地,it重返的迭代元素正是IGrouping。通过

        For Each Dim g In odd

            Console.WriteLine(“Key: ” &
g.Key)

        Next

就能够将享有的组的音信表示出来。(IGrouping里面仅有多个Key属性,它回到当前组的分组关键字类型的对应值。)

我们还是可以越发获得各类组下边包车型大巴剧情,比方

        For Each Dim g In odd

            Console.WriteLine(“Key: ” &
g.Key)

            For Each Dim _g In
g

               
Console.WriteLine(_g)

            Next

        Next

这时候,_g的种类就是Integer了。大家得以将分组操作看成是两层集结的嵌套,外层是独具得到的足的集聚,内层是各个组里面包罗的元数据的集中。

 

    Public Property ItemStatus(ByVal item As T) As rowStatus
        Get
            If CoreDictionary.ContainsKey(item) Then
                Return CoreDictionary(item)
            Else
                Return Nothing
            End If

        End Get
        Set(ByVal value As rowStatus)
            CoreDictionary.Item(item) = value
            If value = rowStatus.Deleted Then
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(“VisibleItems”))
            End If
        End Set
    End Property

    Public Sub Add(ByVal item As T) Implements System.Collections.Generic.ICollection(Of T).Add
        CoreDictionary.Item(item) = rowStatus.UnChanged
        CoreList.Add(item)
        AddHandler item.PropertyChanged, AddressOf Row_PropertyChanged

        RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Add, True, CoreList.IndexOf(item)))

    End Sub

    Public Sub AddNewRow(ByVal item As T)
        CoreDictionary.Item(item) = rowStatus.Inserted
        CoreList.Add(item)
        RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Add, True, CoreList.IndexOf(item)))

    End Sub

    Public Sub Clear() Implements System.Collections.Generic.ICollection(Of T).Clear
        CoreDictionary.Clear()
        CoreList.Clear()
        RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Reset))

    End Sub

    Public Function Contains(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Contains
        Return CoreList.Contains(item)
    End Function

    Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of T).CopyTo
        CoreList.CopyTo(array, arrayIndex)

    End Sub

    Public ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of T).Count
        Get
            Return CoreList.Count
        End Get
    End Property

    Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of T).IsReadOnly
        Get
            Return False
        End Get
    End Property

    Public Function Remove(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Remove

        CoreDictionary.Remove(item)
        Dim res As Boolean = CoreList.Remove(item)

        RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Remove, item, CoreList.IndexOf(item)))

        Return res

    End Function

    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return CoreList.GetEnumerator

    End Function

    Public Event CollectionChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged

    Public Overloads Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return CoreList.GetEnumerator
    End Function

    Public Function IndexOf(ByVal item As T) As Integer Implements System.Collections.Generic.IList(Of T).IndexOf
        Return CoreList.IndexOf(item)
    End Function

发表评论

电子邮件地址不会被公开。 必填项已用*标注