Entity Framework AddRange: how to map to stored procedure? - entity-framework

I am working with EF and stored procedures for data modification operations. So far I have been able to map stored procedures to basic operations such as Insert, Update, and Delete for one row (entity).
However, I would like to map also AddRange. I need a dedicate stored procedure for this operation and it does not work for me that EF calls my add stored procedure n times. I would like that it calls my AddRange stored procedures once.
I would also like to map another common tasks as Clear but for now AddRange is my top priority. Is this kind of mapping possible in EF? If not, is this something that would make sense to add or I am looking into the wrong direction?

I assume you are talking about AddRange which is an extension method of DbSet.
You can't map a store procedure to AddRange or Clear, because these methods are just preparing the entities and nothing will be added to database until SaveChanges is called.
If you need to Add multiple records with one db call, you can call it like this and not with DbSet
public class Context : DbContext
{
public void AddList()
{
this.Database.SqlQuery<YourEntityType>("storedProcedureName",params);
}
}

Related

Does Entity Framework make one database call per operation?

I am trying to profile EF to understand more of its inner workings, I have tried to add two entities using the Add method and the AddRange method, then of course committing with the SaveChanges method. And here is what I got on the profiler in both cases.
Does this mean that EF actually makes two trips to the database one per insert? which means that if I am trying to insert 100 entities for example this will mean 100 trips to the database? which will greatly impact performance. or am I missing something here?
Yes, that is correct, it will issue one database call per item attempting to be added, as it is using the standard SQL INSERT command in this case.
The alternatives would be to use BULKINSERT, such as using a stored procedure that takes in an object such as a DataTable.

Ignore class property except for stored procedure in EF Core

.NET Core 1.1.0, EF Core 1.1.0. I'm querying some things from my DB in such a way that it's much more efficient to delegate to a stored procedure. I want some extra things returned that aren't part of my standard class, so until ad-hoc return types are supported I've added these extra properties to my base class. The problem, however, is that EF now expects columns for each of these properties during all other calls.
If I configure these additional properties with this:
entity.Ignore(p => p.PropertyName);
the properties are ignored when I pull from the stored procedure. I don't know of any other way around this.
How can I get these extra properties returned from the stored procedure but ignore them all other times?
I'm running the query like this (docs):
var popular = await _context.Posts
.FromSql("EXEC usp_Post_Popular {0}, {1}", start, popCount)
.ToListAsync();
I was able to solve this by creating a new class solely for returning the results of these procedures. I created a DbSet in my context configuration for the classes and called .FromSql() on those. No configuration is necessary in OnModelCreating(); I added nothing to that function.

Atomic transactions in Entity Framework 4.1 Code First without stored procedures

Is there a way to implement transactions in code first without having to write stored procedures?
I have some scenarios where multi-table entries need to be created with unique guids before a final table entry can be created. Is this something I can code using EF alone?
DbContext.SaveChanges() method uses a transaction . So it is Atomic and you don't want to use stored procedures. The unitOfWork patter is implemented in EF itself to accomplish this.
But let's say you are using two DbContext instances to d your job , then you need to wrap your work with a transaction scope like this,
using (var scpe=new TransactionScope()){
...
context1.SaveChanges();
....
context.SaveChanges();
scope.Complete();
}
SaveChanges operates within a transaction. SaveChanges will roll back
that transaction and throw an exception if any of the dirty
ObjectStateEntry objects cannot be persisted.
See the documentation

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.