The short question is, can I make EF perform an update when the Poco class has a value for the primary key field and an insert otherwise? Exactly the way NHibernate does.
Unless I'm mistaken the EF way is really ugly.
First instead of using .Add(entity) for inserts or updates you .Add for inserts and for updates:
context.MyEntities.Attach(entity);
I tried that but nothing was saved at all. After reading this I saw I was missing setting the changed state? But my context doesn't have an ObjectStateManager so I need something like:
var manager = ((IObjectContextAdapter)dbContext).ObjectContext.ObjectStateManager;
This seems like a very convoluted and inelegant approach to me. Can I make EF work the way NHibernate does? (If not I'm still early enough in the project that I can rip EF out and go back to using NHibernate)
You have to use the context.Add(entity) in order for Entity Framework to know that it needs to track changes on that object. If the entity already exists in the context, EF will automatically track changes to it and push those changes to the database when you call context.SaveChanges().
You are attaching an entity so you should try EntityState = Modified before savechanges.
Related
In Entity Framework it's easy enough to get an existing item without tracking:
context.Widgets.AsNoTracking().Single(x=>x.Id == id);
What if I want to add a new item without tracking it once it's added? As soon as you do this:
context.Widgets.Add(newWidget);
the instance is tracked. Even if I detach the instance from the context, once it's attached again the context still keeps track of OriginalValues and introduces the usual issues with concurrent updates etc.
Is there a way to:
add a new entity
and/or:
attach an existing detached entity
to a DbContext while enforcing the equivalent AsNoTracking behaviour?
Try this:
context.Widgets.Add(newWidget);
context.SaveChanges();
context.Entry(newWidget).State = EntityState.Detached;
Edit:
The DbContext class, with its stateful nature, was made to track data changes.
This approach made EntityFramework not suited to be used with types that are designed to be transient, like seem to be the "Widget" instance.
The code above should be doing the job: reuse a data structure to be used in a 'semi-persistent' context, but should be optimized with batching.
The reason I commented 'Use Dapper' is that I've been very frustrated in the past by EF, which creates a lot more problems than it solves. Using a stateless Orm is a lot more efficient.
I'm implemented the unit of work like this tutorial explained:
http://www.codeproject.com/Articles/543810/Dependency-Injection-and-Unit-Of-Work-using-Castle
Though now I encounter a strange problem.
I load within a unit of work (in the transaction) an entity from the database
I update a property of that entity
I call not the save method on my repository
The transaction is committed
In this scenario, I would expect that the updated property is not persisted to the database. But it is. So an entity loaded in my session is tracked and committed to the database without calling save. What is causing this? And is there a way to tell Nhibernate not to update those entities if the save is not called?
I realize I can work around this to update only a property when I need to update. The only risk is by accident updating the property by mistake and it is then very hard to find this problem. (and for example someone new, not knowing this could easily make a mistake)
The explanation requires understanding the difference between a transient and a persistent entity. A transient entity is a new entity and it is made persistent by calling Save(). An entity that has been retrieved using NHibernate is already persistent and any changes made to it will be automatically saved when the session is flushed. NHibernate's goal is to make the database consistent with the domain model when the session ends.
See chapter 9 in the documentation.
I'm using Entity Framework 6 Code First, and would like to create a Trigger.
How do I do this?
The reason I need the trigger is because a user may either edit the database directly or through a program I'm writing, and I need to make sure 2 columns in a table are not both null, and are not both not null.
I've been looking and can't find a way.
Is there any way to specify a trigger using code first?
Entity Framework has no support for triggers, although you can certainly manually execute a statement that would create a trigger, but you would need to do this after the table was created (if using migrations).
You can use the technique specified by Ladislav in EF 4.1 code-first adding a trigger to a table
Take note of his warning, however, EF will not be aware of any changes made in the trigger. If your intent is merely to ensure that 2 columns in a table are not null, you'd be better served with a constraint (constraints are also not supported by EF, but you can add them manually).
Check out my library EntityFramework.Triggers. It works at the Entity Framework layer, so the trigger events won't fire if someone modifies the database directly. The NuGet link is https://www.nuget.org/packages/EntityFramework.Triggers/
After you add a migration, open the migration file and create your trigger as shown below
Note: you need to run update-database to see the changes in your database.
First, a little background. I have a DataContext object (Linq to SQL). I use this to interact with my SQL database. I'm using C# in Visual Studio 2010.
The problem is this: I can edit an entry from an entity table that I want. I select the entity with a query, change the particular field, then submit the data context changes. But let's say that I get a separate entity. This entity is actually an edited version of one of the existing entities. So what wants to happen is for this one to overwrite that one. Now, yes, this is possible. You check the primary key, and overwrite the fields from the old one with the fields of the new one. So where's the problem? The problem is if the entity has 40+ fields, it's a pain to assign each field individually. Is there no method or way of doing this more quickly?
Thanks.
You can use the Attach() method. If an entity with the same ID already exists in the database, it will be overwrirtten with the attached entity.
myDataContext.Customers.Attach(myCustomer);
myDataContext.SubmitChanges();
You can use Automapper framework for that purpose. Also it can be used for multiple routine needs as mapping for example
We are making use of EF change tracking in order to fire certain events. For example, if a person entity has an e-mail address change, we can send an e-mail to an administrator or something of that nature.
I'm wondering if there's an easy way to call something like CheckForChangesOnAttach(entity) that would query the db for the current data and compare with the detached entity to set certain properties as updated. Seems like something that shouldn't be too hard to do myself other than attaching large graphs of detached entities, which is why I'm wondering if there's something like that built in (we're using code first, btw).
Our system doesn't do much with detached entities, so 99% of the time we wouldn't need something like that, so I'm not too concerned about performance.
Yes there is such option for single entity (you must load the entity by key and call ApplyCurrentValues on its ObjectSet - it will push new values from detached entity to attached one) but there is no option for object graphs - you must roll your own solution for object graphs.