2010-10-15 3 views
6

У меня есть метод, который возвращает группу счетовВозвращаемый типа для коллекции из запросов LINQ

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 и инфраструктурой сущности.

ответ

7

При распространении результатов запроса LINQ из методов таким образом наилучшим выбором для типа возврата является IEnumerable(Of T) для LINQ для объектов или IQueryable(Of T) для других поставщиков LINQ. В этом случае это выглядит так: Account - это тип IEnumerable(Of Account) или IQueryable(Of T) в зависимости от типа запроса.

+1

лучший выбор - 'IEnumerable', за исключением случаев, когда лучшим вариантом является' IQueryable'. ;) –

+0

@ Кирк, правда. Забыл об этом случае для не LINQ для объектных запросов – JaredPar

2

Лучший тип будет

IEnumerable<Account> 

или синтаксис correspounding в VB: P

На самом деле, все функции LINQ (.Where(), .Distinct() и т.д.) являются методы расширения для IEnumerable<T>, чтобы я подумаю является хорошей практикой продолжать цепочку таким же образом.

+0

Я искал MSDN, но должен смотреть не в том месте. Откуда вы знаете, что WHERE() и Distinct() являются методами расширения IEnumerable . Я не спрашиваю тебя, мне просто интересно, где искать в следующий раз, у меня есть аналогичный вопрос. –

+0

@Travis без проблем. На самом деле в MSDN не совсем очевидно «где» эти методы расширения определены ... но вы можете найти список на странице «IEnumerable ' (общая версия): http://msdn.microsoft.com/ en-us/library/9eekhta0.aspx. Существует небольшая иконка, которая говорит, что это метод расширения ...и когда вы нажимаете на один из них, вы можете видеть, в каком пространстве имён существует ... То есть, чтобы использовать любой метод расширения LINQ, вам нужно иметь 'using System.Linq;' в верхней части файла. – tsimbalar

+0

О, и как я это знал, просто потому, что VS всегда добавляет ссылку на 'System.Linq', а Intellisense просто предлагает их :-). Извлекая капюшон, все выражения типа «linq» преобразуются в цепочки методов расширения Linq. – tsimbalar

0

Вопрос, который вам нужно задать, заключается в следующем: «Когда мне нужно, чтобы SQL фактически выполнялся?» В LINQ это разница между отложенным и немедленным исполнением. Любой метод, который возвращает IEnumerable<>, должен выполнить запрос, чтобы получить результаты. IQueryable<>, с другой стороны, задерживает выполнение запроса до вызова метода, который возвращает IEnumerable<>. В примере, который вы указали, что может быть быстрее передать результат функции GetAllNotesByUser как IQueryable<>, так что вы запускаете один запрос вместо двух:

public static IQueryable<Account> GetAllNotesByUser(Guid UserId) 
{ 
    ... 
} 

Там могут быть ситуации, когда вам необходимо перечислить результат GetAllNotesByUser без каких-либо дополнительных манипуляций. В таких случаях помните, что вы можете вызвать 'ToList() `для принудительного выполнения запроса.

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

'AsEnumerable' не заставляет выполнение запроса: http://stackoverflow.com/questions/3389855/am-i-misunderstanding-linq-to-sql-asenumerable – nawfal

+0

Да, вы правы. ToList() заставит выполнение. –

+0

Нейл, затем отредактируйте свой ответ. В противном случае это гарантирует, что :) – nawfal

1

Там хороший ответ here на IEnumerable<T> против IQueryable<T>.

Я бы использовал IQueryable(Of T), если вы хотите еще больше ограничить набор в вызывающем методе, например, с предложением WHERE. В противном случае я бы использовал IEnumerable(Of T), если всем абонентам известно, что они должны выполнить ToList() в результате, если они планируют повторять его несколько раз (в противном случае вы сделали бы несколько вызовов в базе данных). Если вызывающие абоненты не знают, я бы, вероятно, использовал ICollection(Of T) и выполнил ToList() в самом методе.

Смежные вопросы