How to ExecuteSqlCommand in Entity Framework without it being contained in a transaction - entity-framework

I need to execute a stored procedure with Entity Framework.
Normally I call it like this:
this.Context.Database.ExecuteSqlCommand("EXEC edi_UploadTransmission");
However, this particular stored procedure includes accessing a linked server.
Since EF wraps ExecuteSqlCommand in a transaction, it is failing, as a linked server is not supported in a transaction (as far as I can tell).
Is there a way to execute this stored procedure with Entity Framework without it being in a transaction?

Pass TransactionalBehavior.DoNotEnsureTransaction as the first parameter to the ExecuteSqlCommand method.
For example,
this.Context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "EXEC edi_UploadTransmission");

My recommendation would be to simply not use EF for this part of your code. You can freely combine EF with straight ADO.NET code or with other ORMs such as Dapper or Chain.
https://github.com/docevaad/Chain/wiki/A-Chain-comparison-to-Dapper

Related

Possible to call a stored procedure on a Table-Per-Hierarchy table in EF Core 3.1?

I'm moving from EF Core 2.2 to 3.1. One breaking change (#15392) was that it no longer composed over stored procedures, so you had to add 'AsEnumerable'. That usually works, but I have a stored procedure call on a TPH table where that fails:
My call to the SPROC is:
SqlParameter authorizedUserID_p =
new SqlParameter("#authorizedUserID", authorizedUser.ID);
IEnumerable<Post> query =
context.Posts.FromSqlRaw<Post>("Post.USP_ReadPost #ID, #AuthorizedUserID",
parameters: new[]{ parentID_p, authorizedUserID_p }
).AsEnumerable<Post>();
Post targetPost = query.ToList<Post>().FirstOrDefault<Post>();
And it produces this error, recommending using AsEnumberable (which I'm already using above):
System.InvalidOperationException: FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it.
Consider calling AsEnumerable after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side.
I believe the reason is because my Posts table is Table-per-hiearchy, as other calls to SPROCS in the same application are working fine. Would appreciate any help possible!
This is yet another issue introduced by EFC 3, tracked by #18232: Impossible to use stored procedures related to entities that inherits another one.
The reason is that SP calls are not composable, and EF Core always try to compose SQL for TPH base entities in order to add discriminator condition. Similar to Global Query Filters, but there you can at least use IgnoreQueryFilters, while here you have no option.
The good news is that it's already fixed in EFC repository. The bad news is that it won't be released until EFC 5.0.
Since AsEnumerable() doesn't help, all you can do is to wait for EFC 5.0. Or, if possible, convert SPs like this to TVF (table valued functions) which are composable. In general, use scalar functions or stored procedures with output parameter(s) for non query returning calls (to be executed with ExecuteSql*), and table valued functions for single query returning calls (to be used with FromSql*). Note that currently EFC does not support multiple query returning stored procedures anyway.

How does Entity Framework convert an EntityTransaction into a provider specific transaction?

I've got an Entity Framework 4 data mode. I'm loading data into a database using stored procedures since EF is so slow. We use the entity model to call the stored procedures. Everything has to be in one transaction.
In order to speed up the process, I need to perform some bulk copy operations. I'm using SQL Anywhere and their ADO.NET provider software for this.
When I call context.Connection.BeginTransactin(), I get an EntityTransaction back. Actually, my variable is a DbTransaction, which is the base class for all transactions. But the actual object returned is an EntityTransaction.
I can't cast an EntityTransaction into the provider specific transaction class (SAConnection in this case). If I do, I get a cast exception. Yet, somehow, when the entity context calls the stored procedures, it's enlisting the provider specific command objects it creates into the transaction represented by that EntityTransaction object.
How does the provider do this? Is it a mechanism I can use to get a provider-specific transaction object for my bulk copy operations?
Tony
I have taken a look at the EntityTransaction class and in fact an internal property called StoreTransaction exists. If found some source-code in this SO discussion: This SqlTransaction has completed; it is no longer usable. Entity Framework Code First which might help you out.
Keep in mind, that this won't work in partial trust environments, which do not allow you to access members using reflection.

Debugging stored procedure while in use with Entity Framework

I have DocumentItem entity mapped to insert/update/delete stored procedures in Entity Framework edmx.
I'm trying to insert a new Document into the databse along with its DocumentItems. The whole operation is enclosed in a transaction, and it's not easy to debug separately.
This is why I would like to try to debug the sp 'live' - when it's called from entity framework. Is it possible at all?
Just use profiler to see what data EF sends to stored procedure and use that data separately to test / debug only stored procedure. Debugging it together requires you to set debugging session for both .NET code and SQL code and place breakpoint into stored procedure prior to calling SaveChanges on your context. In theory it could work but I never use that.

Entity Framework only with stored procedures

i have a question about the reasonableness of using entity framework only with stored procedures in our scenario.
We plan to have an N-tier architecutre, with UI, BusinessLayer (BLL), DataAccessLayer(DAL) and a BusinessObjectDefinitions(BOD) layer. The BOD layer is known by all other layers and the results from executes queries in the DAL should be transformed into Objects (definied in the BOD) before passing into the BLL.
We will only use stored procedures for all CRUD methods.
So in case of a select stored procedure, we would add a function import, create a complex type and when we execute the function, we tranform the values of the complex type into a class of BOD and pass that to the BLL.
So basicly, we have no Entities in the Model, just Complex types, that are transformed into Business Objects.
I'm not sure if that all makes sense, since in my opinion, we lose a lot of the benefit, EF offers.
Or am i totally wrong?
I would not use EF if all I was just using was stored procs.
Personally, I'd look at something like PetaPoco, Massive or even just straight Ado.Net
EDIT
Here's an example of PetaPoco consuming SPs and outputting custom types
http://weblogs.asp.net/jalpeshpvadgama/archive/2011/06/20/petapoco-with-stored-procedures.aspx
I disagree with both of the existing answers here. Petapoco is great, but I think the EF still offers a number of advantages.
Petapoco works great (maybe even better than the EF) for executing simple stored procedures that read a single entity or a list of entities. However, once you've read the data and need to begin modifying it, I feel this is where the EF is the clear winner.
To insert/update data with petapoco you'll need to manually call the insert/update stored procedure using:
db.Execute("EXEC spName #param1 = 1, #param2 = 2")
Manually constructing the stored procedure call and declaring all the parameters gets old very fast when the insert/update stored procedures insert rows with more than just a couple of columns. This gets even worse when calling update stored procedures that implement optimistic concurrency (i.e. passing in the original values as parameters).
You also run the risk of making a typo in your in-lined stored procedure call, which very likely will not be caught until runtime.
Now compare this to the entity framework: In the EF I would simply map my stored procedure to my entity in the edmx. There's less risk of a typo, since the entity framework tools will automatically generate the mapping by analyzing my stored procedure.
The entity framework also will handle optimistic concurrency without any problems. Finally, when it comes time to save my changes the only step is to call:
entities.SaveChanges()
I agree, if you rely on stored procedures for all CRUD methods, then there is no need to use EF.
I use EF to map stored procedure calls as our DAL. It saves time in writing your DAL by mapping the functions. We are not using LINQ to SQL as much, as our DBA does not want direct data table access.

Is it possible to override the ObjectContext.SaveChanges method in entity Framework?

I was wondering if it is possible to override the ObjectContext.SaveChanges() method and write our own sql logic to save the changes made to the entities in the object context instead of relying on Entity Framework to save those changes in the database.
Generally you can do anything you want if you override SaveChanges and do not call base.SaveChanges but you will loose all the stuf EF will do for you. It means you will have to manually browse metadata and map your entities to SQL tables and columns. There will be like writing half the ORM yourselves.
If you just need some little custom logic when persisting entity you can map imported stored procedure to Insert, Update and Delete operations in the entity designer.
In EF4 SaveChanges(SaveOptions) is virtual. You can override this method. MSDN
#Ladislav is correct that a stored proc is one way to do this (+1).
Another way is to write a wrapper provider.