Is there a way to execute the DbContext.SaveChanges() without invoke its internal auto transaction handling?
I'm working to handle the transaction (DbTransaction) myself, but when I invoking it's Commit, I getting error "SqlConnection does not support parallel transactions"
I believe this is due to SaveChanges is doing its own internal transaction work, which I want to suppress it.
.NET 4.5, EntityFramework.dll ver 5.
googling shows few approaches, but the code are not compatible.
Some showing SaveChanges can accept a Boolean, which it is not in this ver. and then invoking AcceptAllChanges() which method also not exist.
While some is using System.Transaction.TransactionScope, but its different with this System.Data.Common.DbTransaction.
after many PITA efforts digging over the EF thing. the only way I found out to have proper transaction control over it is best to use ObjectContext, instead of DbContext.
http://sqlanywhere-forum.sap.com/questions/11320/entity-framework-savechanges-closes-connection
this hinted the ObjectContext
DbContext codebase is genereated if your EDMX code generation strategy is set to None.
link: Is ObjectContext deprecated in .NET 4.5?
by changing it to Default, you will get ObjectContext code base gen.
the diff of them so far of what I found out, using DbContext, whenever you invoke its SaveChanges(), it will AUTO close the underneath connection, and your next db task will have a new connection, which basically break the transaction control of what I seek.
you need to run the whole db tasks without the conx being close or recreate within the transaction.
by using ObjectContext, SaveChanges() will not auto close the connection if I setup the transaction and connection codes properly before it.
Related
As a follow-up to Axon Event Published Multiple Times Over Eventbus, when using an EmbeddedEventStore and publishing a command that will attempt to create an instance of an aggregate that already exists, Axon is not throwing an exception indicating the instance exists (or constraint violation), as is on the contrary, when using Axon's JPA event store. Is this the expected behavior? If so, why?
Recently our community filed a similar issue to our repo that I am going refer here.
Essentially the JPA or JDBC implementation are responsible for catching this kind of exceptions and translating them to something the Framework understands.
If that occurs, you should see an AggregateStreamCreationException dispatched, indicating that it failed and why it failed. If this is not happening I recommend you looking into your PersistenceExceptionResolver.
If you still see this happening after checking what I shared, this is likely a bug and in this case, feel free to open it on our repo as such.
At the start-up of our application we call EF code first's Database.Initialize(force=true) method to initialize the local database. On some computers when the user attempts to start up the application right after logging in to the user account the Migrations are triggered and the application crashes because the first Migration tries to add tables to the database that are already there. The second (or third) time the user launches the application no Migrations are triggered and the application starts up succesfully.
So to summarize:
The application starts.
It calls Database.Initialize(true);
EF does not see the database and triggers the Migrations to create it.
The first Migration tries to add tables to the database and crashses because the database was there after all.
This behaviour is only seen after a launch of the application shortly after logging in.
Does anyone have any inkling to about what is going on?
EDIT
Extra info:
We use EF 6.1.3
We assign the initializer thus: Database.SetInitializer(New DbInitializer), DbInitializer inheriting MigrateDatabaseToLatestVersion(Of OurDbContext, Migrations.Configuration)
I notice now that the DbInitializer is assigned in the static constructor of OurDbContext , but that the Database.Initialize method is invoked from another class. This may very well be the root of the problem.
The problem seems indeed to be related to the fact the assignment of the MigrateDatabaseToLatestVersionimplementation was called in the static constructor of the DbContext while the Database.Initialize call comes from an other class. On some systems it seems then that the initializer is changed from DropCreate to Migrate halfway during initialization, or that the connection string changes.
I recently upgraded an application from .net 3.5 to 4.0. Since I did that, with debug settings to break on all exceptions enabled, I've been getting a few of these exceptions each time I start a section of the application that connects to a database using the EF. The exact number is variable; sometimes I only get one, others several in rapid succession.
ReleaseHandleFailed was detected Message: A SafeHandle or
CriticalHandle of type
'Microsoft.Win32.SafeHandles.SafeCapiHashHandle' failed to properly
release the handle with value 0x06AD3D08. This usually indicates that
the handle was released incorrectly via another means (such as
extracting the handle using DangerousGetHandle and closing it directly
or building another SafeHandle around it.)
I never got exceptions like this when targeting 3.5. These exceptions don't have any meaningful call stack attached, all I get is [External Code], denying any easy way to localize where they're coming from. The reason I suspect EntityFramework is somehow involved is that one section of the app uses nHiberate instead doesn't generate any of these messages.
To run down other dependencies that might be involved: In all cases, the ORM is talking to an Sql Compact database MS Sync Framework 2.1 is being used to update the local DB from SqlServer. The Entity framework models have been regenerated with the 4.0 framework, and I upgraded the cache DB to v4.0 as well.
Since there's no call stack I'm not sure if these messages fall into the category of "harmless" errors automatically cleaned up internal to the framework; or if there's an exception eater catching them elsewhere in the application.
This is not an exception, it is a Managed Debugging Assistant warning. You might have gone over-board a bit when you changed the settings to "break on all exceptions enabled". Debug + Exceptions, Managed Debugging Assistants node, untick the "ReleaseHandleFailed" warning. It is off by default.
The MDA catches an old bug that's gone undetected for a while in the AesCryptoServiceProvider class. Backgrounder is here.
Judging from your comment, you are about to make a drastic mistake. You do not solve this by avoiding encryption or compromising your dbase connection security. You accidentally turned on an MDA that's normally off. MDAs in general tend to produce false warnings and many of them are turned off by default. The warning is in fact bogus, releasing the handle failed because it was already released. This happens in the finalizer thread, that's why you don't get a stack trace. And thus can't easily find out what code uses the class in the first place.
The proper way to fix it is to use the Debug + Exceptions dialog properly. Fix the problem you created by clicking the Reset All button. Then click only the Thrown checkbox for Common Language Runtime exceptions. That's what you are trying to debug.
After using EFProfiler (absolutely fantastic tool BTW!) for profiling a few of our Entity Framework applications, it seems that, in most cases, all of the Object Contexts are not closed.
For example, after running it locally, EF Profiler told me that there were 326 Object Context's opened, yet only 1 was closed?
So my question is, should I worry about this? Or is it self-contained within Entity Framework?
If you're not using an IoC container is there anyway you can close the ObjectContexts manually after each request, for example in the End Request of your Global.asax, thereby simulating a "per request" lifestyle for your contexts?
ObjectContexts will be disposed eventually if your application is not holding onto them explicitly, but in general, you should try to dispose them deterministically as soon as possible after you are done with them. In most cases, they will hold onto database connections until they are disposed. In my current web application, we use an IoC container (Autofac) to ensure that any ObjectContext opened during a request is disposed at the end of the request, and does not have to wait for garbage collection.
I suggest you do worry about it and try to fix the issue as Object Contexts are pretty "bulky". If you have too many of them your application may eventually end up using more memory than it needs to and IIS will be restarting your application more frequently then...
I want the SaveChanges of the ObjectContext (Win apps) to save changes asynchronously, will show a marquee (or controllable?) progress bar (this I can easily implement) for the user while he is able to continue working.
I basically want to override the SaveChanges of the ObjectContext.
Has anyone thought about this before?
Entity Framework itself currently does not support asynchronous operations. Mainly because it's built on top of ADO.NET where this isn't supported either. ADO.NET isn't even thread safe by default.
You can use the delegate approach above or wrap it into Task. But that will not use any async calls even if the provider supports it. Also during this "background" operation you should not do anything with the ObjectContext (querying, adding objects, ...) as may result in corrupted state.
Related to multithreading you can read this post. It's older, but ideas are still valid.
Edit 2013-04-17:
EF6 (the next version, currently in alpha stage in time of writing) will support asynchronous operations, namely your requested SaveChangesAsync. It also extended ADO.NET model, so if the provider itself supports asynchronous execution it will be really asynchronous (else back to former behavior as there's nothing better (wise) to do).
Warning: The answer below is old and may not apply to the most recent versions of the framework in question.
I believe you need to use Asynchronous Delegates. It basically works like that:
You create a delegate from the method you want to call asynchronously;
You call BeginInvoke on the delegate, starting a call;
You do whatever else you need to do (e.g. animate a marquee);
You can either wait for the async call to finish, or check whether is has completed and keep animating the marquee if it isn't;