tags:

views:

424

answers:

3

I am calling the LINQ extension method AsQueryable off of a generic list. It throws StackOverflowException exception when I access it. This is a similar technique used in the NerdDinner asp.net mvc demo app. What am I doing wrong?

    class FakeUserRepository : IUserRepository
    {
        List<User> users = new List<User>();

        public FakeUserRepository() {
            users.Add(new User() {
                UserID = new Guid("2C3028AC-B51C-4AA6-8E19-AF962AC07EE7"),
                DisplayName = "User1"
            });

            users.Add(new User() {
                UserID = new Guid("EBA48956-2BFE-4C03-8D1B-29747FA7DB25"),
                DisplayName = "User2"
            });
        }

        public IQueryable<User> Users {
            get { return users.AsQueryable(); }
        }
    }

    public interface IUserRepository
    {
        IQueryable<User> Users { get; }
    }

public class MyController : Controller
{
    IUserRepository _userRepository;

    public MyController(IUserRepository userRepository) {
        _userRepository = userRepository;
    }

    protected override void Execute(System.Web.Routing.RequestContext requestContext) {
        Guid userID = new Guid("2C3028AC-B51C-4AA6-8E19-AF962AC07EE7");

        if (requestContext.HttpContext.Request.IsAuthenticated) {
            var query = (from u in _userRepository.Users
                         where u.UserID == userID
                         select new {
                             u.DisplayName
                         }).FirstOrDefault();

            ViewData["displayName"] = query.DisplayName;
        }

        base.Execute(requestContext);
    }
}
+2  A: 

Stack trace is your friend. Does the exception come from AsQueryable or from your own class?

In the mean time, check that get { return users.AsQueryable(); } doesn't say get { return Users.AsQueryable(); }

Juliet
+1  A: 

The code you posted here works fine. I'm going to guess you're real code does something like this.

public IQueryable<User> Users
{
    get { return Users.AsQueryable(); }
}

Note the capitalization of Users in Users.AsQueryable().

wekempf
+1  A: 

Maybe is a bug. And was corrected in LINQ 4.0

http://damieng.com/blog/2009/06/01/linq-to-sql-changes-in-net-40

Query stability Contains now detects self-referencing IQueryable and doesn't cause a stack overflow

In .NET 3.5 to resolve the problem: When using 'Auto Generated Value' = True, then you must set 'Delay Loaded' to False - otherwise you get the recursion error.

Jader Dias