关于vb.net:Return来自LINQ查询的集合类型

Return Type for Collection from LINQ Query

我有一个方法,它返回一组帐户

1
2
3
4
5
6
7
8
Public Shared Function GetAllNotesByUser(ByVal UserID As Guid) As Account (??)
    Using db As New MyEntity
        Dim query= (From A In db.Account _
                    Where A.aspnet_Users.UserId = UserID _
                    Select A)
        Return query
    End Using
End Function

然后我想把这个传递给另一个函数来计算集合中所有帐户的合计。返回IEnumerable和泛型列表是最佳实践吗?我只是不确定什么最适合Linq和实体框架。


以这种方式传播方法的LINQ查询结果时,返回类型的最佳选择是对于LINQ to对象的IEnumerable(Of T)或对于其他LINQ提供程序的IQueryable(Of T)。在这种情况下,看起来Account是类型,因此IEnumerable(Of Account)IQueryable(Of T)取决于所讨论的查询类型。


最好的类型是

1
IEnumerable<Account>

或在vb:p中对应的语法

实际上,所有的linq函数(.Where().Distinct()等)都是IEnumerable的扩展方法,我认为用同样的方式继续这个链是一个很好的实践。


这里有一个很好的答案,关于IEnumerableIQueryable

如果您想进一步限制方法调用方中的集合,例如使用WHERE子句,我将使用IQueryable(Of T)。否则,如果所有调用方都知道如果计划多次迭代结果,他们需要对结果执行tolist(),那么我将使用IEnumerable(Of T)(否则,您将对数据库进行多次调用)。如果调用方不知道,我可能会使用ICollection(Of T)并在方法本身中执行tolist()。


您需要问的问题是:"我何时需要实际执行SQL?"在Linq中,这是延迟执行和立即执行之间的区别。任何返回IEnumerable<>的方法都必须执行查询才能获得结果。另一方面,IQueryable<>会延迟查询的执行,直到对返回IEnumerable<>的方法进行调用。在您提供的示例中,将GetAllNotesByUser函数的结果作为IQueryable<>传递可能会更快,因此您只运行一个查询而不是两个查询:

1
2
3
4
public static IQueryable<Account> GetAllNotesByUser(Guid UserId)
{
    ...
}

在某些情况下,您可能需要在不执行任何其他操作的情况下枚举GetAllNotesByUser的结果。在这些情况下,请记住,您可以调用"tolist()"来强制执行查询。

1
var result = GetAllNotesByUser(<guid>).ToList();