I have the following method:
public IEnumerable<Foo> GetFoo(int x, string y)
{
return from r in new GetFoo(x, y)
select new Foo
{
x = r.Get<int>("x"),
y = r.Get<string>("y"),
z = r.Get<DateTime?>("z"),
};
}
GetFoo is a class that contains a stored procedure and implements IEnumerable<DbDataReader>. So, r is a DbDataReader.
I want it to execute the query where the query syntax is declared and return a List<Foo>.
If this is not done, it is my understanding that the caller could simply not iterate the whole list and then the database connection will not be closed. I know I can just put it in parenthesis and call ToList() but I want to avoid this if possible. We have 200+ stored procedures, and it is too easy for a developer to miss adding the ToList().
Is there something I can implement to make what I want happen?
Update
This is not linq to sql, I have created a custom class, GetFoo that implements IEnumerable<DbDataReader>. The IEnumerator<DbDataReader> that is returned looks like this:
private class Enumerator : IEnumerator<DbDataReader> {
DbDataReader _;
public Enumerator(DbDataReader r) { _ = r; }
public DbDataReader Current { get { return _; } }
public void Dispose() { _.Dispose(); }
object System.Collections.IEnumerator.Current { get { return _; } }
public bool MoveNext() { return _.Read(); }
public void Reset() { throw new NotImplementedException(); }
}
Update 2
I can’t really enforce calling ToList() and/or requiring List<Foo> to be the return type of this method, and others like these. Developer review should catch not converting it to a list. Unfortunately if its missed there and in QA testing the application will run just fine. I’m simply trying to prevent a situation where the database connection could be left open.
Linq is based on deferred loading. It is when you call ToList that it executes the command. Otherwise it does not execute it. So the answer to your questions is no. However, I am not sure, maybe code contracts can help where you mark methods, or call the above code in functions which returns a List. In that case developers will be bound to return a List. Otherwise the code will not compile.