有没有更好的方法来执行此LINQ语句块?

时间:2009-08-13 22:33:03

标签: asp.net vb.net linq refactoring

我对LINQ比较陌生,但我会更多地进入它。以下是LINQ的实际应用,还是有更好的方法来做这样的事情?

Public Shared Function GetItems(ByVal itemsList As List(Of OrderItem), 
 ByVal whichForm As ItemsFor, ByVal formID As Integer) As List(Of OrderItem)
    Dim items As New List(Of OrderItem)
    Select Case whichForm
        Case ItemsFor.MfrCredit
            Dim query = From oi As OrderItem In itemsList _
Where oi.ManufacturerCreditID = formID Select oi
            items = query
        Case ItemsFor.CustomerCredit
            Dim query = From oi As OrderItem In itemsList _
 Where oi.CustomerCreditID = formID Select oi
            items = query
        Case ItemsFor.Invoice
            Dim query = From oi As OrderItem In itemsList _
 Where oi.InvoiceID = formID Select oi
            items = query
        Case ItemsFor.PurchaseOrder
            Dim query = From oi As OrderItem In itemsList _
 Where oi.PurchaseOrderID = formID Select oi
            items = query
        Case ItemsFor.Quote
            Dim query = From oi As OrderItem In itemsList _
 Where oi.QuoteID = formID Select oi
            items = query
        Case ItemsFor.StockingOrder
            Dim query = From oi As OrderItem In itemsList _
 Where oi.StockingOrderID = formID Select oi
            items = query
    End Select
    Return items
End Function

我在想是否可以以某种方式获取属性名称作为对象我可以只做一个LINQ语句,但我不确定如何......

谢谢!

5 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

Dim condition As Func(Of OrderItem, Boolean)
Select Case whichForm
    Case ItemsFor.MfrCredit
        condition = Function(oi As OrderItem) oi.ManufacturerCreditID = formID
    Case ItemsFor.CustomerCredit
        condition = Function(oi as OrderItem) oi.CustomerCreditID = formID
    ...
End Select
Return items.Where(condition).ToList()

它并不完美,但至少它的代码重复较少......

答案 1 :(得分:2)

您可以使用Predicate代表。我想象一个数组或谓词列表,每个ItemsFor一个。

然后您的查询

Dim query = From oi As OrderItem In itemsList Where predicate select oi 

另见this article on building predicatesthis article on PredicateBuilder

答案 2 :(得分:1)

您可以使用LINQ表达式,如下所示:(我的VB生锈,因此可能无法编译)

Dim param = Expression.Parameter(GetType(OrderItem), "item")
Dim getter = Expression.Lambda(Of Func(Of OrderItem, Integer))( _
    Expression.Property(param, whichForm.ToString()), _
    param _
).Compile()

Return items.Where(Function(item) getter(item) == formId)

为获得最佳性能,请将生成的代理缓存在Dictionary(Of ItemsFor, Func(Of OrderItem, Integer))

修改

System.Linq.Expressions命名空间允许您在运行时创建函数。此coe使用该功能创建一个获取属性的函数。由于Compile方法(实际创建函数)有点慢,因此最好重用每个生成的委托。

答案 3 :(得分:0)

您可以将其转换为单个查询的一种方式是:

Dim query = From oi As OrderItem In itemsList _
Where ((whichForm = ItemsFor.MfrCredit) and (oi.ManufacturerCreditID = formID)) _
or ((whichForm = ItemsFor.CustomerCredit) and (oi.CustomerCreditID = formID)) _
or ((whichForm = ItemsFor.Invoice) and (oi.InvoiceID = formID)) _
...
select oi
items = query

答案 4 :(得分:0)

通过手动创建表达式树,Linq中的动态搜索有一个很好的article here ...相当多的工作。或者另一个(更好?)选项是Dynamic Linq上的这篇文章(这里的例子是C#)