views:

50

answers:

4

I have a method, that returns a group of accounts

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

I would then like to pass this to another function to calculate the totals for all the accounts in the collection. Is it best practice to return an Ienumerable, a generic list, I'm just not sure what works best with LINQ and the entity framework.

+4  A: 

When propagating LINQ query results from methods in this manner, the best choice for the return type is IEnumerable(Of T) for LINQ to objects or IQueryable(Of T) for other LINQ providers. In this case it looks like Account is the type so IEnumerable(Of Account) or IQueryable(Of T) depending on the query type in question.

JaredPar
@JaredPar, the best choice is `IEnumerable` except when the best choice is `IQueryable`. ;)
Kirk Woll
@Kirk, true. Forgot about that case fro non-LINQ to object queries
JaredPar
A: 

The best type would be

IEnumerable<Account>

or the correspounding syntax in VB :P

Actually, all the LINQ functions (.Where() , .Distinct() etc) are extension methods to IEnumerable<T>, to I think it is good practice to continue the chain in the same way.

tsimbalar
I've searched MSDN, but must be looking in the wrong place. How do you know that WHERE() and Distinct() are extension methods of IEnumerable<T>. I'm not questioning you, I'm just wondering where to look next time I have a similar question.
Travis Gneiting
@Travis no problem. Actually in the MSDN, it is not really obvious "where" those extension methods are defined... but you can find the list on the page for `IEnumerable<T>` (generic version) : http://msdn.microsoft.com/en-us/library/9eekhta0.aspx . There is a small icon that says it is an extension method ... and when you click on one of them, you can see in which namespace it lives ... That is, in order to use any LINQ extension method, you need to have `using System.Linq;` at the top of your file.
tsimbalar
Oh, and the way I knew it, is just because VS always adds a reference to `System.Linq` and the Intellisense just suggests them :-) . Behing the hood, all the "linq" query-like expressions are converted into chains of Linq extension methods.
tsimbalar
and now I think of it, I think some Ling Method extensions apply to `IEnumerable<T>` , but some apply to `IQueryable<T>`
tsimbalar
A: 

The question you need to ask is: "When do I need the SQL to actually be executed?" In LINQ, it's the difference between deferred and immediate execution. Any method that returns an IEnumerable<> has to execute the query in order to get the results. IQueryable<>, on the other hand, delays execution of the query until a method that returns an IEnumerable<> is called against it. In the example you provided, it may be faster to pass the result of the GetAllNotesByUser function as an IQueryable<>, so that you run a single query instead of two:

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

There may be situations where you need to enumerate the result of GetAllNotesByUser without performing any additional manipulation. In those cases, remember you can call AsEnumerable<Account>() to force execution of the query.

var result = GetAllNotesByUser(<guid>).AsEnumerable<Account>();
Neil T.
A: 

There's a good answer here on IEnumerable<T> vs IQueryable<T>.

I would use IQueryable(Of T) if you would like to further limit the set in the caller of the method, for example with a WHERE clause. Otherwise I would use IEnumerable(Of T) if all callers are aware that they need to perform a ToList() on the result if they plan to iterate it more than once (otherwise you would make multiple calls to the database). If callers are not aware, I would probably use ICollection(Of T) and perform the ToList() in the method itself.

DonAndre