tags:

views:

83

answers:

5

Is there a better way of doing this?

I have a Linq-To-SQL query that I need to return objects defined by abstract interfaces (e.g. IList<IUser>) rather than concrete objects (e.g. List<User>).

// get users from data context

        List<User> users;

        using (AbleridgeDataContext context = new AbleridgeDataContext())
        {

            users = (from u in context.Users select u).ToList();
        }

        // reassign concrete users to abstract interfaces

        IList<IUser> genericUsers = new List<IUser>();

        foreach (var user in users)
        {
            IUser genericUser = user;
            genericUsers.Add(genericUser);
        }

        return genericUsers;
+2  A: 
return context.Users.Cast<IUser>().ToList();

Alternatively:

List<IUser> users = new List<IUser>(context.Users);
Juliet
A: 

Try this instead. It will return IEnumerable<IUser>

using (AbleridgeDataContext context = new AbleridgeDataContext())
{
    return context.Users.Select((IUser)u);
}

If you really want IList then set your function return type to IList<IUser> and add a .ToList() to the end of the return statement.

Or

return context.Users.OfType<IUser>();
gbogumil
A: 

You could cast to IUser in the projection part of the query:

    List<User> users;
    using (AbleridgeDataContext context = new AbleridgeDataContext())
    {
        return from u in context.Users select (IUser)u;
    }

The one change this would require is to make your function return IEnumerable<IUser> which would be better anyway because the query won't be executed until the caller begins enumerating.

Though you could also just use ToList still if you're not interested in changing that.

Update Actually you probably will want to use ToList here because the using statement is disposing of your data context as soon as the function returns so a lazy query would fail.

joshperry
+1  A: 

Declare users as IList and cast User to IUser with linq.

ToList returns an IEnumerable, which is implemented my IList and List, so it really doesn't matter which one you declare users as.

    IList<IUser> users;
    using (AbleridgeDataContext context = new AbleridgeDataContext())
    {
        users = (from u in context.Users select u).Cast<IUser>().ToList();
    }
Mikael Svenson
A: 

From the MSDN website:

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)

Have you tried context.Users.ToList<IUser>()?

Also regarding the context, the ToList method will force the query to be evaluated so the result will be available after the context is disposed.

Alka