I’m facing a pretty weird construct. The Foo type returned in an IEnumerable loses its data as soon as the enumeration ends. This means that I can’t do a enumeration.First() because the data would be lost right away.
A loop over it works, but since I know it will contain only a single element that would be weird.
int Test(out int something)
IEnumerable<Foo> enumeration = ...
for (var foo in enumeration) {
something = foo.GetSomething ();
return foo.GetAnInt ();
}
something = 42;
return 0;
}
Another way I though of is abusing a Linq Select, but that’s just as horrible.
Is there a way to work around this limitation? Fixing the root cause is obviously superior, but difficult in this case.
Edit: It’s an IEnumerable<IDataRecord> that is yield returned from a transactioned SQL data reader.
public IEnumerable<IDataRecord> ExecuteReader (SqlCommand cmd)
{
using (var con = GetConnection()) {
con.Open ();
using (var tr = con.BeginTransaction ()) {
cmd.Connection = con;
var reader = cmd.ExecuteReader ();
while (reader.Read ()) {
yield return reader;
}
tr.Commit ();
}
}
}
The problem is that your
ExecuteReadermethod does simply return theSqlDataReaderitself (which implementsIDataRecord), instead of returning a block of data. So when you do this:In that case all elements of the list will be the same
SqlDataReaderinstance, but after theToListhas been executed, the reader has been closed. I’m a bit surprised that you don’t get anObjectDisposedException.For this to work, you need to return a copy of the data in the
IDataRecord. You think you can iterate the elements in the data record. An other option is to change theExecuteReaderto the following:This way you can do the following:
Note: I’m not sure why you need a transaction for this anyway.