Reputation: 2589
I don't know if the question is properly formatted but what I'm trying to do is to create the var reservations
outside the using
loop but don't know how to initialize it.
This code works :
using (MainContextDB db = new MainContextDB())
{
var reservations = (from c in db.Reservations select new { c.CustAcctNo, c.ReservNo, c.ReservStatus }).ToList();
}
Any attempt to declare the var
outside the loop will trigger an error:
Cannot convert List to List
I've tried:
var reservations = new List<dynamic>();
var reservations = new List<object>();
This code works, but requires to retrieve all columns, which is not what I want:
List<Reservation> reservations = new List<Reservation>();
using (MainContextDB db = new MainContextDB())
{
reservations = db.Reservations.ToList();
}
Upvotes: 2
Views: 717
Reputation: 9587
Note: I would use none of the below approaches in performance-sensitive code.
Having said that, I am seeing a very simple solution here which can also be applied when you're dealing with types other than List<T>
. A bit of type inference gets the job done:
private T InvokeAndReturn<T>(Func<T> func)
{
return func();
}
Usage:
// reservations is List<'a>.
var reservations = this.InvokeAndReturn(() =>
{
using (var db = new MainContextDB())
{
return db.Reservations
.Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
.ToList();
}
});
Fresh edit
Just had to use this in my own code and opted for an IDisposable
-aware alternative instead:
TReturn Using<TDisposable, TReturn>(TDisposable disposable, Func<TDisposable, TReturn> func)
where TDisposable : IDisposable
{
try
{
return func(disposable);
}
finally
{
if (disposable != null)
{
disposable.Dispose();
}
}
}
Usage:
var reservations = Using(new MainContextDB(), db =>
{
return db.Reservations
.Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
.ToList();
});
Or an even shorter version
var reservations = Using(new MainContextDB(), db =>
db.Reservations
.Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
.ToList()
);
Upvotes: 0
Reputation: 117019
You could do it this way:
var reservations = new []
{
new { CustAcctNo = "", ReservNo = "", ReservStatus = "" }
}.ToList();
using (MainContextDB db = new MainContextDB())
{
reservations = (
from c in db.Reservations
select new
{
c.CustAcctNo, c.ReservNo, c.ReservStatus
}).ToList();
}
You just have to make sure you match the types on the members of your anonymous class.
The other option is to add a reference to the Microsoft Reactive Framework Team's "Interactive Extensions". They have a nice Using
method for enmerables that lets you do this:
var reservations =
EnumerableEx
.Using(
() => new MainContextDB(),
db =>
from c in db.Reservations
select new
{
c.CustAcctNo, c.ReservNo, c.ReservStatus
})
.ToList();
Upvotes: 2
Reputation: 7288
Ok that ended up being a really interesting question-
I know that anonymous types aren't supposed to leave the method context, hadn't really thought about them leaving scope though...
I see a few possible options...
Do something hackey - Two anon types with the same signature share the same type, so you could coerce it into accepting a prototype and go from there. (converting into a list is difficult but doable in generics... see the link posted by simo)
Move the operations into your using context which I know isn't ideal
Manually dispose the context
Handle the items as dynamic
You could substitute a custom type or a tuple for the anonymous type
Hope that helps, I'm somewhat suprised there isn't a straightforward way to do this if you are remaining inside a method scope.
Upvotes: 1