using the enterprise library cache application blocks in asp.net mvc2 - asp.net-mvc-2

I tried to use the cache application blocks of the microsoft enterprise library. I have used the MS Enterprise Library V5.0
Here is the sample code i have made, inside the home controller's index method.
Person p = new Person(10, "person1");
ICacheManager cacheMgr = CacheFactory.GetCacheManager("myCache");
ViewData["Message"] = "Welcome to ASP.NET MVC!";
if (Session["currsession"] != null)
{
if (!cacheMgr.Contains(p.pid.ToString()))
{
Response.Write("item is not in cache");
return View(p);
}
else
{
Response.Write("item is still in cache");
return View(p);
}
}
else
{
Session["currsession"] = 1;
cacheMgr.Add(p.pid.ToString(), p, CacheItemPriority.High, null, new SlidingTime(TimeSpan.FromSeconds(10)));
return View(cacheMgr.GetData(p.pid.ToString()));
}
The person class i use in the model has just a constructor with 2 public properties. Nothing special features are used.
Now, is this the right procedure to use the caching of the enterprise library caching blocks. If not, how else can i code this block of code in an efficient manner.
Also, i get the response as item is not in cache only after 20 second delay. Is there any mistake in the implementation of the code or is there a theory behind the caching in detail.
Kindly suggest the best practice for this usage.

Since you specify a sliding expiration of 10 seconds, that means that you will get item is not in cache if you wait more than 10 seconds between reloading the page.
Load first time in session => no message
Reload => in cache
Reload => in cache
Wait 10 seconds
Reload => not in cache
Is this what you're seeing?
Old answer:
The enterprise caching application block is probably way more than you need. My favorite cache is FubuMVC's Cache (just include FubuCore.dll). You can get a very similar implementation by using a ConcurrentDictionary with a "missing element" delegate. Here's an example: http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/37bbc361-6851-43db-9e90-80cc7e6ac15f
FubuMVC Cache example:
public class PersonCache
{
private Cache _Cache = new Cache();
public PersonCache()
{
_Cache.OnMissing = key => MyDatabase.People.GetById(key);
}
public Person GetById(int id)
{
return _Cache[id];
}
}

Related

WPF : Update View Model when DB Changes (Concurrency Issue)

I'm currently working on WPF app that is architectured as follows:
MVVM
Entity Framwork 4 (with LINQ).
WCF service that pool Database to get data (Oracle).
I Make my WFC call in my View Model Class and put my data in an ObsevableCollections.
Db Changes occurs from a another app.
So my app does not do any write actions on the DB what-so-ever (Zéro), it only reads data and displays it on the UI.
How can I make my app to be quickly responsive to DB changes, I read about the following solutions but I'm confused and don't know what to use:
Pooling DB every n seconds with a DispatcherTimer (seems to be too much work cause data changes every millisecond)
SqlDependency, searched all over the internet but didn't find a proper implementation with EF.
As I said, db changes every millisecond (financial data from other sources),
How can resolve this?
Thank you.
i tried the code bellow and it seemed to be working okay for the moment (but i still have some doubts about that infinit loop), let me know what you thing :
public class MyViewModel
{
BackgroundWorker _bgWorker ;
//some props
//some funcs
protected internal MyViewModel(Session session)
{
Session = session;
RefreshData();
}
protected void RefreshData()
{
try
{
_bgWorker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bgWorker.DoWork += bgDoWork;
if (!_bgWorker.IsBusy)
{
_bgWorker.RunWorkerAsync();
}
}
catch (Exception)
{
_bgWorker.CancelAsync();
}
}
private void bgDoWork(object sender, DoWorkEventArgs e)
{
var worker = (BackgroundWorker)sender;
while (!worker.CancellationPending)
{
//Thread.Sleep(1000); should i keep this or not ?
Proxy(); // WCF calls
}
}
}

Using Reactive Extensions to stream model changes

I am working on a server component which is responsible for caching models in memory and then stream any changes to interested clients.
When the first client requests a model (well model key, each model has a key to identify it) the model will be created (along with any subscriptions to downstream systems) and then sent to the client, followed by a stream of updates (generated by downstream systems). Any subsequent client's should get this cached (updated) model, again with the stream of updates. When the last client unsubscribes to the model the downstream subscriptions should be destroyed and the cached model destroyed.
Could anyone point me in the right direction as regards to how Rx could help here. I guess what isn't clear to me at the moment is how I synchronize state (of the object) and the stream of changes? Would I have two separate IObservables for the model and updates?
Update: here's what I have so far:
Model model = null;
return Observable.Create((IObserver<ModelUpdate> observer) =>
{
model = _modelFactory.GetModel(key);
_backendThing.Subscribe(model, observer.OnNext);
return Disposable.Create(() =>
{
_backendThing.Unsubscribe(model);
});
})
.Do((u) => model.MergeUpdate(u))
.Buffer(_bufferLength)
.Select(inp => new ModelEvent(inp))
.Publish()
.RefCount()
.StartWith(new ModelEvent(model)
If I understood the problem correctly, there are Models coming in dynamically. At any point in time in your Application's lifetime, the number of Models are unknown.
For that purpose an IObservable<IEnumerable<Model>> looks like a way to go. Each time there is a new Model added or an existing one removed, the updated IEnumerable<Model> would be streamed. Now it would essentially preserve the older objects as opposed to creating all Models each time there is an update unless there is a good reason to do so.
As for the update on each Model object's state such as any field value or property value changed, I would look into Paul Betts' ReactiveUI project, it has something called ReactiveObject. Reactive object helps you get change notifications easily, but that library is mainly designed for WPF MVVM applications.
Here is how a Model's state update would go with ReactiveObject
public class Model : ReactiveObject
{
int _currentPressure;
public int CurrentPressure
{
get { return _currentPressure; }
set { this.RaiseAndSetIfChagned(ref _currentPressure, value); }
}
}
now anywhere you have Model object in your application you could easily get an Observable that will give you updates about the object's pressure component. I can use When or WhenAny extension methods.
You could however not use ReactiveUI and have a simple IObservable whenever a state change occurs.
Something like this may work, though your requirements aren't exactly clear to me.
private static readonly ConcurrentDictionary<Key, IObservable<Model>> cache = new...
...
public IObservable<Model> GetModel(Key key)
{
return cache.GetOrAdd(key, CreateModelWithUpdates);
}
private IObservable<Model> CreateModelWithUpdates(Key key)
{
return Observable.Using(() => new Model(key), model => GetUpdates(model).StartWith(model))
.Publish((Model)null)
.RefCount()
.Where(model => model != null);
}
private IObservable<Model> GetUpdates(Model model) { ... }
...
public class Model : IDisposable
{
...
}

Nested DbContext due to method calls - Entity Framework

In the following case where two DbContexts are nested due to method calls:
public void Method_A() {
using (var db = new SomeDbContext()) {
//...do some work here
Method_B();
//...do some more work here
}
}
public void Method_B() {
using (var db = new SomeDbContext()) {
//...do some work
}
}
Question:
Will this nesting cause any issues? (and will the correct DbContext be disposed at the correct time?)
Is this nesting considered bad practice, should Method_A be refactored into:
public void Method_A() {
using (var db = new SomeDbContext()) {
//...do some work here
}
Method_B();
using (var db = new SomeDbContext()) {
//...do some more work here
}
}
Thanks.
Your DbContext derived class is actually managing at least three things for you here:
the metadata that describes your database and your entity model,
the underlying database connection, and
a client side "cache" of entities loaded using the context, for change tracking, relationship fixup, etc. (Note that although I term this a "cache" for want of a better word, this is generally short lived and is just to support EFs functionality. It's not a substitute for proper caching in your application if applicable.)
Entity Framework generally caches the metadata (item 1) so that it is shared by all context instances (or, at least, all instances that use the same connection string). So here that gives you no cause for concern.
As mentioned in other comments, your code results in using two database connections. This may or may not be a problem for you.
You also end up with two client caches (item 3). If you happen to load an entity from the outer context, then again from the inner context, you will have two copies of it in memory. This would definitely be confusing, and could lead to subtle bugs. This means that, if you don't want to use shared context objects, then your option 2 would probably be better than option 1.
If you are using transactions, there are further considerations. Having multiple database connections is likely to result in transactions being promoted to distributed transactions, which is probably not what you want. Since you didn't make any mention of db transactions, I won't go into this further here.
So, where does this leave you?
If you are using this pattern simply to avoid passing DbContext objects around in your code, then you would probably be better off refactoring MethodB to receive the context as a parameter. The question of how long-lived context objects should be comes up repeatedly. As a rule of thumb, create a new context for a single database operation or for a series of related database operations. (See, for example this blog post and this question.)
(As an alternative, you could add a constructor to your DbContext derived class that receives an existing connection. Then you could share the same connection between multiple contexts.)
One useful pattern is to write your own class that creates a context object and stores it as a private field or property. Then you make your class implement IDisposable and its Dispose() method disposes the context object. Your calling code news up an instance of your class, and doesn't have to worry about contexts or connections at all.
When might you need to have multiple contexts active at the same time?
This can be useful when you need to write code that is multi-threaded. A database connection is not thread-safe, so you must only ever access a connection (and therefore an EF context) from one thread at a time. If that is too restrictive, you need multiple connections (and contexts), one per thread. You might find this interesting.
You can alter your code by passing to Method_B the context. If you do so, the creation of the second db call SomeDbContext will not be necessary.
there a question an answer in stackoverflow in this link
Proper use of "Using" statement for datacontext
It is a bit late answer, but still people may be looking so here is another way.
Create class, that cares about disposing for you. In some scenarios, there would be a function usable from different places in solution. This way you avoid creating multiple instances of DbContext and you can use nested calls as many as you like.
Pasting simple example.
public class SomeContext : SomeDbContext
{
protected int UsingCount = 0;
public static SomeContext GetContext(SomeContext context)
{
if (context != null)
{
context.UsingCount++;
}
else
{
context = new SomeContext();
}
return context;
}
private SomeContext()
{
}
protected bool MyDisposing = true;
protected override void Dispose(bool disposing)
{
if (UsingCount == 0)
{
base.Dispose(MyDisposing);
MyDisposing = false;
}
else
{
UsingCount--;
}
}
public override int SaveChanges()
{
if (UsingCount == 0)
{
return base.SaveChanges();
}
else
{
return 0;
}
}
}
Example of usage
public class ExmapleNesting
{
public void MethodA()
{
using (var context = SomeContext.GetContext(null))
{
// manipulate, save it, just do not call Dispose on context in using
MethodB(context);
}
MethodB();
}
public void MethodB(SomeContext someContext = null)
{
using (var context = SomeContext.GetContext(someContext))
{
// manipulate, save it, just do not call Dispose on context in using
// Even more nested functions if you'd like
}
}
}
Simple and easy to use.
If you think number of connections to Database,and impact of times that new connections must be opened, not an important problem and you have no limitation for support your application to run at best performance, everything is OK.
Your code works well. Because create just a db context has a low impact in your performance,meta data will be cached after first loading, and connection to your database just occurs when the code need to execute a query. With liitle performance consideration and code design, I offer you to make context factory to have just an instance of each Db Context for each instance of your application.
You can take a look at this link for more performance considerations
http://msdn.microsoft.com/en-us/data/hh949853

querying in EntityObject

I have partial class TaxReportItem with partial method OnActualVolumeChanging(double value):
public partial class TaxReportItem
{
partial void OnActualVolumeChanging(double value)
{
if (Tax != null)
{
Payment = value*Tax.TaxRate;
}
}
}
In this method i want to get all collection of TaxReportItems that's present in context(something like this):
partial void OnActualVolumeChanging(double value)
{
var sum = 0.0;
if (Tax != null)
{
Payment = value*Tax.TaxRate;
foreach (var taxReportItem in ????)
{
sum += taxReportItem.Sum;
}
}
}
How can i achieve this?
This is actually quite hard because you should never need this. If you need this, design of your entity object is wrong and it is doing something which should be done elsewhere. Single TaxReportItem should never need to know about other tax report items and load them from database unless other items are dependent on this item (they form an aggregate). In such case you should have navigation property to dependent items in the principal one.
To follow your question. If you need to load other items you must have instance of the context to do that. You can either get instance used to load current item and use it to load other entities (bad solution) or you can create a new instance of the context and use it to load other entities (even worse solution).
As you can see from the linked article getting current context instance from the entity itself is not easy and it has some prerequisites which goes back to the first paragraph. It is hard because it is wrong approach.

MVC 2 and EF4 Self-tracking entities models have bad state on post back

I've got standard Create() Edit() and Delete() methods on my controllers, and I am using the EF4 Self-tracking entities.
When the edit is posted back, the model.ChangeTracker.ChangeTracking = false, and model.ChangeTracker.State = ObjectState.Added, even though I made sure those are set when retrieving the record initially.
Are the self-tracking entities not persisting the ChangeTracker class when the form is submitted? If so, how do I fix that?
public virtual ActionResult Edit(int personId)
{
IContext context = ContextFactory.GetContext();
EntityRepo Repo = new EntityRepo(context);
Person d = Repo.Person.GetById(PersonId);
d.ChangeTracker.ChangeTrackingEnabled = true;
return View(d);
}
[HttpPost]
public virtual ActionResult Edit(int personId, Person item)
{
try
{
if (ModelState.IsValid)
{
IContext context = ContextFactory.GetContext();
EntityRepo Repo = new EntityRepo(context);
// the item is returning these properties that are wrong
//item.ChangeTracker.ChangeTrackingEnabled = false;
//item.ChangeTracker.State = ObjectState.Added;
Repo.Person.Update(item);
Repo.Person.SaveChanges();
return RedirectToAction("Index");
}
}
catch
{
}
return View();
}
Let's start at the beginning.
What are Self-Tracking Entities, exactly?
A Self-Tracking Entity is an entity which can do change tracking even when it is not connected to a ObjectContext. They are useful in times when you must change the entity, but cannot have it connected to an ObjectContext.
So when would I want one, really?
Mostly, when you must have distributed objects. For example, one use case is when you are making a web service which talks to a Silverlight client. However, other tools, like RIA Services may be a better fit here. Another possible use case is for a long-running task. Since an ObjectContext is intended to be a unit of work and should typically not be long-lived, having a disconnected entity might make sense here.
Do they make any sense for MVC?
Not really, no.
Let's look at this a little deeper, and examine what happens when you update an entity in MVC. The general process is like this:
The browser issues a GET request for an update page.
The MVC app fetches an entity, and uses it to build an update HTML page. The page is served to the browser, and most C# objects, including your entity, are disposed. At this point, you can restart the Web server, and the browser will never know the difference.
The browser issues a POST request to update the entity.
The MVC framework uses the data in the POST in order to materialize an instance of an edit model which is passed to the update action. This might happen to be the same type as the entity, but it is a new instance.
The MVC app can update the entity and pass those changes back to the database.
Now, you could make self-tracking entities work by also including the full state of the STE in the HTML form and POSTing that back to the MVC app along with the scalar values on the entity. Then the Self-Tracking Entity might at least work.
But what benefit does this give you? The browser obviously cannot deal with your entity as a C# object. So it cannot make any changes to the entity worth tracking in terms that a Self-Tracking Entity would understand.
U should keep original STE in some hidden field. It's like your custom ViewState. In submit method u must merge original STE and new values.
Use ActionFilterAttribute for it.
Like
public class SerializeOriginalModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if (viewResult == null)
return;
var viewModel = viewResult.ViewData.Model as ViewModel;
if (viewModel == null || viewModel.SteObject == null)
return;
byte[] bytes;
using (var stream = new MemoryStream())
{
var serializer = new DataContractSerializer(viewModel.SteObject.GetType());
serializer.WriteObject(stream, viewModel.SteObject);
bytes = stream.ToArray();
}
var compressed = GZipHelper.Compress(bytes);
viewModel.SerializedSteObject = Convert.ToBase64String(compressed);
}
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionParameters == null || filterContext.ActionParameters.Count == 0)
return;
var viewModel = filterContext.ActionParameters.First().Value as ViewModel;
var serialized = filterContext.HttpContext.Request.Form["SerializedSteObject"];
if (viewModel == null || String.IsNullOrEmpty(serialized))
return;
var type = filterContext.ActionParameters.First().Value.GetType().BaseType.GetGenericArguments()[0];
var bytes = GZipHelper.Decompress(Convert.FromBase64String(serialized));
using (var stream = new MemoryStream(bytes))
{
var serializer = new DataContractSerializer(type);
viewModel.SteObject = serializer.ReadObject(stream);
}
}
}
STE has one very big drawback. You have to store them in session or view state (WebForms). So it is nothing more than "new version of dataset". If you don't store STE you will have one instance for getting data and different for posting = no change tracking.
I think you are missing the idea of Repository. You should not have an Update method in the Repository. After submitting, you should get the item again, apply the modifications and then Save.
I prefer having a service layer between client and Repository. We can always change the strategy with which we merge.
And yes, if you need to persist your STE's between requests, use session or viewstate.
It should be
Repo.Person.ApplyChanges(item);
Repo.Person.SaveChanges();
instead of
Repo.Person.Update(item);
Repo.Person.SaveChanges();
Self Tracking works with ApplyChanges extention method.