Reputation: 20668
I am developing an ASP.NET MVC project, and I would like to lazy-load a database DataContext object that is used across Class
es within a server Request (that is, it only live through a Request, and for each Request, I have an unique object).
Currently I can obtain the Request using HttpContext.Current
or HttpContext.Current.Request
, but the Request only stores string values.
Is there something like the Session
object, but for the Request only? Something like the ViewBag or ViewData, but accessible from the HttpContext
object?
EDIT: Here is what I am trying to achieve: I have a AccountBusiness
class, that might be instantiated multiple times in a request. It has LoggedInUser
property (note: this is not the AspNetUser object of ASP.NET Identity) that is lazy-loaded. Normally I would do something like this:
private UserProfile loggedInProfile;
public UserProfile LoggedInProfile
{
get
{
if (this.loggedInProfile == null)
{
var userId = HttpContext.Current.User.Identity.GetUserId();
this.loggedInProfile = this.Context.UserProfiles.FirstOrDefault(q => q.ID == userId);
}
return this.loggedInProfile;
}
}
However, as I stated before, this property might be instantiated multiple times in a request, it will access the database multiple time for just a same UserProfile object. This is just an example, I have much more objects similar to this, and would like to change so that it only access the database once, then save it for using for the current Request, like this:
public UserProfile LoggedInProfile
{
get
{
if (this.loggedInProfile == null)
{
var dataTokens = HttpContext.Current.Request.RequestContext.RouteData.DataTokens;
object o;
if (!dataTokens.TryGetValue("CurrentUserProfile", out o))
{
var userId = HttpContext.Current.User.Identity.GetUserId();
dataTokens["CurrentUserProfile"] = o = this.Context.UserProfiles
.FirstOrDefault(q => q.ID == userId);
}
this.loggedInProfile = o as UserProfile;
}
return this.loggedInProfile;
}
}
Is there any bad thing in my solution?
P.s: I just discover RouteValues
and DataTokens
may contain a key-object
pair, but I wonder if it is okay to use it?
Upvotes: 1
Views: 1695
Reputation: 995
Use the HttpContext.Items collection to share objects during the lifetime of the request.
Upvotes: 5
Reputation: 4146
Use dependency injection and Inversion of Control. Most IOC tools, like Castle Windsor, will allow you to have your context persisted for the life of a request.
If you are not familiar with DI, here is a simple example:
Mycontroller
{
IMyContext _contex;
public Mycontroller(IMyContext context)
{
_context = context;
}
}
Upvotes: 0
Reputation: 239300
I would like to lazy-load a database DataContext object that is used across the Request only.
That bit troubles me. Perhaps it's just worded awkwardly, but it sounds as if you're somehow trying to persist your context across requests, which would be a very bad idea.
If, however, you're just talking about persisting the results of a query or similar, I'd recommend using the in-memory caching provided by ASP.NET. Using session or cookies involves relying on the client to store information, and that's both unnecessary and inappropriate for this kind of thing.
Upvotes: 1
Reputation: 461
You can use Cache or Cookie both are accessible with HttpContext and after using you can make empty them.
Upvotes: 0