Trigger a Session Update when an object is updated elsewhere - c#

I have a custom object that is referenced many times throughout a module in my system. Let me refer to it as CustomObj. To minimize the constant loading of this object from the DB I'd like to store it in Session in a collection of those objects. So I'd like to store a Dictionary of CustomObj where the key is the ID of the CustomObj. That way I can just check the Session if they key exists, then just reference that CustomObj over and over again, without the hit on the DB every time.
However, these CustomObjs can be updated by an Admin and their properties change. When that happens I'd like to broadcast down to the users connected to update that object in the dictionary to use the latest properties. Is there a built in process for doing this or would I need to implement some sort of broadcast and force an update via SignalR (I already have a hub setup for Facebook like notifications). Is Session the right place for this ?
The objects won't be updated extremely frequently or by alot of different Admins, but every once in a while the Admin will make a change to 1-5 properties, save, and the object is now different.

It's not an ideal way to store an object in a session that is being modified by different users. In your case, Caching should be the recommended solution.

Related

NHibernate calling "get" from a property twice

I have this situation: I'm developing a software with Spring.net and Fluent NHibernate, and I noticed something very unusual with NHibernate's behavior. I really don't know whether it's correct or not, but for my software it cannot happen. I noticed that NHibernate is calling twice all the getters, even when I'm updating something on the database. For exemple, when I try to insert some values on dabatase, NHibernate gets the value from the property to put on database, and then it triggers a new get again, which I don't know why and how is called. I think it tries to retrieve the value from cache to compare both values (database and cache) and save the updated value on cache.
By the way, for some entities I have a secondary cache level, but this situation happens with entities that have and don't have this secondaty cache level.
Any help? Thank you.
You should be able to find it out using print of current stack track
in particular getter and compare it to other traces. This should
show you starting point.
What get into my mind:
Backward get for caching because of second level cache as it stores properties of entities only.
What about has-code computing? Is it use properties to or fields?
Verification whether object in session is as same in the database.
If with get you mean NHibernate runs a select on the database to retrieve the object, within an insert/update this will be done only if you provide the ID of the object and the object is not already available within the session.
If you don't have the object in the database and want NHibernate to insert a new one, do not provide an ID and configure the generator of your ID map correctly
Otherwise make clever use of proxies and prevent NHibernate to retrieve the full object by using Load<T> which will not actually hit the database but puts a proxy into the current session scope.

Implementing object change tracking in an N-Tier WCF MVC application

Most of the examples I've seen online shows object change tracking in a WinForms/WPF context. Or if it's on the web, connected objects are used, therefore, the changes made to each object can be tracked.
In my scenario, the objects are disconnected once they leave the data layer (Mapped into business objects in WCF, and mapped into DTO on the MVC application)
When the users make changes to the object on MVC (e.g., changing 1 field property), how do I send that change from the View, all the way down to the DB?
I would like to have an audit table, that saves the changes made to a particular object. What I would like to save is the before & after values of an object only for the properties that we modified
I can think of a few ways to do this
1) Implement an IsDirty flag for each property for all Models in the MVC layer(or in the javascript?). Propagate that information all the way back down to the service layer, and finally the data layer.
2) Having this change tracking mechanism within the service layer would be great, but how would I then keep track of the "original" values after the modified values have been passed back from MVC?
3) Database triggers? But I'm not sure how to get started. Is this even possible?
Are there any known object change tracking implementations out there for an n-tier mvc-wcf solution?
Example of the audit table:
Audit table
Id Object Property OldValue NewValue
--------------------------------------------------------------------------------------
1 Customer Name Bob Joe
2 Customer Age 21 22
Possible solutions to this problem will depend in large part on what changes you allow in the database while the user is editing the data.
In otherwords, once it "leaves" the database, is it locked exclusively for the user or can other users or processes update it in the meantime?
For example, if the user can get the data and sit on it for a couple of hours or days, but the database continues to allow updates to the data, then you really want to track the changes the user has made to the version currently in the database, not the changes that the user made to the data they are viewing.
The way that we handle this scenario is to start a transaction, read the entire existing object, and then use reflection to compare the old and new values, logging the changes into an audit log. This gets a little complex when dealing with nested records, but is well worth the time spent to implement.
If, on the other hand, no other users or processes are allowed to alter the data, then you have a couple of different options that vary in complexity, data storage, and impact to existing data structures.
For example, you could modify each property in each of your classes to record when it has changed and keep a running tally of these changes in the class (obviously a base class implementation helps substantially here).
However, depending on the point at which you capture the user's changes (every time they update the field in the form, for example), this could generate a substantial amount of non-useful log information because you probably only want to know what changed from the database perspective, not from the UI perspective.
You could also deep clone the object and pass that around the layers. Then, when it is time to determine what has changed, you can again use reflection. However, depending on the size of your business objects, this approach can impose a hefty performance penalty since a complete copy has to be moved over the wire and retained with the original record.
You could also implement the same approach as the "updates allowed while editing" approach. This, in my mind, is the cleanest solution because the original data doesn't have to travel with the edited data, there is no possibility of tampering with the original data and it supports numerous clients without having to support the change tracking in the UI level.
There are two parts to your question:
How to do it in MVC:
The usual way: you send the changes back to the server, a controller handles them, etc. etc..
The is nothing unusual in your use case that mandates a change in the way MVC usually works.
It is better for your use case scenario for the changes to be encoded as individual change operations, not as a modified object were you need to use reflection to find out what changes if any the user made.
How to do it on the database:
This is probably your intended question:
First of all stay away from ORM frameworks, life is too complex as it.
On the last step of the save operation you should have the following information:
The objects and fields that need to change and their new values.
You need to keep track of the following information:
What the last change to the object you intend to modify in the database.
This can be obtained from the Audit table and needs to be saved in a Session (or Session like object).
Then you need to do the following in a transaction:
Obtain the last change to the object(s) being modified from the database.
If the objects have changed abort, and inform the user of the collision.
If not obtain the current values of the fields being changed.
Save the new values.
Update the Audit table.
I would use a stored procedure for this to make the process less chatty, and for greater separations of concerns between the database code and the application code.

Available frameworks/tools to send change notifications?

Is there a framework that will identify (through comparing the object) when an object property value has changed (user can specify which properties to "watch") and then raise an event/send a notification?
Example: The app stores Person class in a database and keeps a copy in memory. The app retrieves the person data from the database to refresh the copy in memory periodically. Other apps/processes update the person data in the database. I want an event/notification raised when the mood property(list collection of strings: Upbeat,tired, etc.) of the person object is changed.
I know how to code this, but I get the feeling there is something out there that does this. Only two things I can think of that is similar is:
cache notifications, but haven't seen any that allow you to specify which
properties/values to notify on. This would also require one to have a distributed cache server.
sql query notifications - I'm looking into this one.
Your description of the issue sounds a lot like what happens when you work with Entity Framework (and other ORMs). It's possible you could use the Entity Framework, and inspect the objects after they have been processed to detect changes. An example of which you can find here.
Is that the kind of thing you're looking for?
EDIT:
Regarding the Sql Query Notifications, take a look at the SqlDependency Class if you want to head down that route.

NHibernate multiple references to the same record from a single object

I'm using Fluent NHibernate and the setup I have is as follows:
An Address object, which is a simple list of address fields.
A Company object which has two references to address objects, MainAddress, InvoiceAddress.
The problem I'm having is that on occasion both MainAddress and InvoiceAddress may refer to the same record in the Address table.
Addresses are looked up by searching, using something along the lines of:
ICriteria c = session.CreateCriteria(typeof(Address))
.Add(Example.Create(address).ExcludeNone());
Because each Address is selected seperately, this leads to two instances of the same record, which causes NHibernate to puke when trying to save the Company object.
"a different object with the same identifier value was already associated with the session"
What's the best way to work around this?
Thanks!
Unless you are selecting in different sessions and then mixing them (which is incorrect), NHibernate's default behavior is to retrieve the same instance for the same row, no matter how many times you query.
Make sure you're using a single session.
You should use NHibernate's Merge.
merge():
if there is a persistent instance with the same identifier currently
associated with the session, copy the
state of the given object onto the
persistent instance
if there is no persistent instance currently associated with the session,
try to load it from the database, or
create a new persistent instance
the persistent instance is returned
the given instance does not become associated with the session, it
remains detached
It's the same as SaveOrUpdateCopy, but that command's apparently deprecated:
I think SaveOrUpdateCopy is something
that has exited in NHibernate for all
time and Merge is something added in
2.1 (clearly something ported from the hibernate). Anyway I am very glad that
NHibernate has this ability because
writing and handling the merge
operation manually is very boring code
to write!

Session and objects in memory

I'm so confused here. Ok, so I'm trying to create a session object that we can use to store some info.
My plan is to create a new FacebookSession object whenever a user logs into Facebook (after they are redirect back to our site). I can set state for this by using the auto generated cookie that the facebook SDK creates after they've logged into facebook. So I can hopefully grab that cookie when they get back server-side and create my FacebookSession object and set state off the cookie info (userID, token, etc.) that contains info I need for that user's facebook account.
I don't understand session state very well and also threads as it relates to a page. So, can't I check for the existing session object on every page or is it lost when you go from page to page? Lets say I create this initial FacebookSession object when the user gets back and then redirect them immediately thereafter to another page Response.Redirect. Do I lose that object? I think so right? because a new page request spawns a new thread in IIS for that user right? And then you start off with a clean slate in terms of any objects you created in memory have been wiped.
So then I need to persist it in the DB and then with a method such as GetCurrentSession, somehow look up that current user and try to grab current session information in a table lets say called FacebookSession where I could store their facebookUserID, token, etc.
right?
Finally, at any time, how would I know how to check for that user in the DB? I need some sort of unique ID? So what I did was to add a Pk column that actually will utilize an existing sessionID every user on our site has..which is the overall global vistiting session that they get when they visit our site.
So using that I can uniquely identify their facebook Session if it exists by looking it up in my table via their "global session ID". But the problem ultimately that I run into is now in order to call GetCurrentSession() from my FacebookSession.cs object, I need to somehow pass it that global ID. I can do this through the constructor (I'm not making this a singleton). But then now that object and several other objects are dependent on this global ID needed to look up a user's Facebook session. Well what if we want to reuse this library/wrapper I've created in some other project that doesn't want to use the global session as the PK, then I'm kinda screwed.
So this is the headache I have right now. Pretty much I just want some opinions and verification if I'm going down the right path here and if I'm right about memory, IIS, threads, and session state in terms of a way to attack this one.
I guess you should check this description from MSDN.

Categories