I have a repository where I have common methods for adding etc.
And I would like to run 3 methods as a transaction. Is that possible if each of them have "SaveChanges()" in them?
e.g
_somerep.AddCamel("test");
_somerep.AddGoo("test");
_somerep.AddGopher("test");
/Lasse
As long as the repository uses a single entity context and all insertions are handled by a single call to context.SaveChanges(), they are automatically enrolled in a transaction by Entity Framework.
You can also manage transactions via TransactionScope as mentioned here (but I wouldn't suggest it since it requires Microsoft Distributed Transaction Coordinator to be installed...and can cause some weird issues):
How to: Manage Transactions in the Entity Framework
Related
We have a large application that allows the user to switch between different modules within the application. Each module needs to be able to save separately, so each module has it's own EntityManager.
There are some lookup tables, though, that we would like to use across the application. If we load the lookup tables at the application level, using a different EntityManager, they are not very usable then within the modules.
For example, if I want to load a 'Countries' lookup table at the application level, I then can't do something as simple as:
Person.Country = lookupDataContext.getCountry('Norway')
if Person is within a module's EntityManager. I will get something like:
"An Entity cannot be attached to an entity in another EntityManager. One of the two entities must be detached first."
Am I understanding BreezeJS correctly? If so, does that mean I need to have the Countries lookup within each module's EntityManager? This seems very limiting.
I believe this question is related to your other question about having multiple EntityManagers. Check out my general thoughts there which cover the scenario you describe here.
To be slightly more specific:
Breeze entities cannot navigate to related entities in a different EntityManager; that's what the error message is telling you.
You probably do want separate instances of the reference entities (such as Countries) in both managers.
You can easily copy any set of entities from one manager to another with export and import methods. You don't have to go back to the server.
Now, instead of a lookupDataContext, each sandbox datacontext can have a sandboxContext.lookups.countries method that delivers the appropriate entities from the proper sandbox manager.
Is this limiting? I don't think it's so bad as long as
you aren't duplicating an enormous amount of data across managers.
the reference entities are essentially immutable during a user session.
a user session doesn't keep too many sandbox managers alive at the same time
you dispose of or re-cycle the sandbox managers (and their datacontexts) when you're done with them.
You should be able to achieve your goal of loading lookups from the server once and managing them centrally in the master manager.
This approach has been very successful in a great number of applications over the last decade (pre-Breeze obviously).
HTH.
I am building an ASP.NET application using nhibernate and I implemented the session per request architecture. Each request I am opening a session, using it, then closing it. I am using one large object across several views and I am storing the object in user session cache so it maintains state for them across several different pages. The users do not want to have to save their changes on each page, they want the ability to navigate between several pages making changes, then commit them to the DB. This works well except for when the users try to hit a page that triggers lazy loading on the proxy object (which fails due to the session per request design closing the nhibernate session in the previous request). I know that turning lazy loading off would fix it; however, that is not an option due to the performance issues it would cause in other areas. I have tried changing the session per request design but have had no luck since I do not know when it is "safe" to close the nhibernate session.
Has anyone else done anything similar to this or have any advice?
Thanks in advance!
Keeping any objects in user session - the server session, server resource is not the best approach. Just imagine, that accidently your application will be very very successful... and there will be many users... therefore many sessions == many resources.
I would suggest (based on some experience), try to re-think the architecture to avoid session. Extreme would be to go to single page application... but even some async during "...navigation among several pages..." will be better.
All that will mean, that:
we passs data to client (standard ASP.NET MVC way with rendered views or some Web Api JSON)
if needed we send data back to server (binding of forms or formatting JSON)
In these scenarios, standard NHiberante session will work. Why? Because we "reload and reassign" objects with standard NHibernat infrastructure. That would be the way I suggest to go...
But if you want to follow your way, then definitely check the merge functionality of NHibernate:
9.4.2. Updating detached objects
9.4.3. Reattaching detached objects
19.1.4. Initializing collections and proxies
Some cites:
In an application with a separate business tier, the business logic must "prepare" all collections that will be needed by the web tier before returning. This means that the business tier should load all the data and return all the data already initialized to the presentation/web tier that is required for a particular use case. Usually, the application calls NHibernateUtil.Initialize() for each collection that will be needed in the web tier (this call must occur before the session is closed) or retrieves the collection eagerly using a NHibernate query with a FETCH clause or a FetchMode.Join in ICriteria. This is usually easier if you adopt the Command pattern instead of a Session Facade.
You may also attach a previously loaded object to a new ISession with Merge() or Lock() before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!
I am writing inserts and updates into a database using Entity Framework. The issue is that I want to do what I used to do with stored procedures, which is make groups of updates and inserts atomic by putting transactions around them. How is this sort of thing possible with linq to Entities/Entity Framework?
Thanks,
Sachin
When you call SaveChanges it automatically executes everything in single transaction. If you need to group changes into separate transaction you must do them in sequence and call SaveChanges for each group separately.
I saw this Post by ADO.Net team which looks very promising until I started using it in my application. I have EF 4.0 model with close to 100 self tracking entities. After including the iterator in my project, any of the extension methods "StartTrackingAll" or "StopTrackingAll" would take 5sec to finish. Has anyone ran into same issue or anyone knows of any better option.
Are your entities in relation? In that case you don't need to use StartTrackingAll because StartTracking itself starts tracking for whole object graph:
The StartTracking method instructs the
change tracker on the entity to start
recording any changes applied to the
entity. This includes changes to
scalar properties, collections, and
references to other entities. The
self-tracking entities start tracking
automatically when they are
deserialized into the client through
the Windows Communication Foundation
(WCF). The tracking is also turned on
for newly created entities in the
following scenarios:
* A relationship is created between the new entity and an entity that is already tracking changes.
* The MarkAs[State] or AcceptChanges method is called on an entity.
If you are not using related entities it sounds strange that you need to track 100 entities in the same time. Also if entities don't have relations it is perhaps not needed to track them at all.
I am creating a solution in ASP.NET MVC 2, NHibernate and DDD. I am using a semi CQRS type Model.
ASP.NET Controller send validated messaged to Service Layer which updates state of an Domain object.
I have my Domain Dispatch "Events" and these are then caught by "Event Handlers" who act on them. Each of these Event Handler have access to Repository Layer and can commit an Domain Object State.
Event Handlers also insert records directly into reporting based tables using a (non NHibernate ) Repository. Event Handlers may also do non database related operations like sending emails.
Event Handler can also change state of an object thereby creating new set of events.
How can I assure that all database operation that occur during a single asp.net Request are inside a single Transaction.
I have been reading some blogs ( like Kevin Williams , Matt Wrock and Davy Brion) and have got information on how to start a Session object in Begin and End Request ( Again I will be using Structure Map here) but not sure how the transaction is maintained. This was compounded by the fact that start and end Requests may be called on different threads.
My Repository Class takes NHibernate ISession in its Parameter. If I create ISession as Hybrid Scope ( StructureMap) will that ensure that during a request ISession parameter that is passed by StructrueMap remain same.
Please advise and also let me know if my question is not clear.
Thank you,
Mar
The Mar
You can consider implementing the Unit Of Work pattern for each web request. The unit of work creates an NHibernate session and also handles transactions. There are several implementations that you can find on the web such as this and this.
in addition to WorldIsRound's answer- you haven't specified in your description where transactions are created and commited (from your explanation i'm assuming it should be somewhere in the Service layer).
I konw that there are tools that'll manage your sessions, and maybe your transactions, for you, but in my opinion, you want to explicitly control your transactions.
I use UOW pattern in my projects as well, to create a Session object in the Begin_Request event, and then I use that object to create transactions when I need them.
Again, that's just my opinion, but I think you should have complete control over opening and closing your transactions.
Good luck