I'm trying to do a copy of an object in ef-core 2.0. Im using a query that fetches a lot of objects with Include ande then I use the AsNoTracking to tell ef that this is a completly new object.
Im using the default settings and I'm letting the database generate the Ids on insert. But when I use the AsNoTracking-query I still get the id of the original object which gives me an exception on SaveChanges.
SqlException: Cannot insert explicit value for identity column in table 'Plans' when IDENTITY_INSERT is set to OFF.
I dont actually want to change this setting and if i traverse the objects and changes the Id to 0 it works. Is there any way to handle this problem without traversing all the objects?
Is there a better way to do create a copy?
As Ivan comments above there is no better answer than that so check this link out for a better answer. In my case I get the object and the hierarchy in the same way as before then traverse the objects and sets the PK to 0.
Replicate Entire Row In Entity Framework Core
Related
I need to add a new column / property to my database and my model without EF Code First dropping my database.
Is there a way to manually map a column to property so EF would not drop my database?
Update:
Got it to work by following this post on SO.
https://stackoverflow.com/questions/6049135/manually-editing-database-in-code-first-entity-framework
Basically you just need to:
Manually add the column to your database
Manually add the property to your model
Disable any database initializer in your DataContext
As long you're using anything beyond EF 4.3, you would use Migrations to do so. You can't do it manually because EF relies on the model that is stored in order to best do the mapping to SQL. When you make a change it refreshes the model. Any attempt to add something without changing the model will result in an exception.
I have several entities that contain datetime fields for EffectiveAsOf and ExpiredAsOf. When an entity is modified I want to override the SaveChanges method and rather than just update the existing entity have the code save the original record back to the database with an ExpiredAsOf datetime set to the current time, and a new record inserted with the new data and EffectiveAsOf set to the current time with ExpiredAsOf set to null.
I know that the ObjectStateEntry items in the objectStateEntryList contain CurrentValues and Original values objects, as well as an Entity object. What does EF use to write data to the DB the CurrentValues data or the Entity? How do I go about creating a new entry? Or, am I going about this the wrong way entirely?
I know that I can handle this in the entities outside of EF, but would rather have EF detect and handle these entities automatically.
Thanks in advance for your help and insight,
Jim
EF by default will use both - it uses original values to check for a concurrency issue (i.e. if the record has changed since you loaded the data from the DB) then uses the entity's current/modified values to update the DB record.
It is not possible to have EF "detect and handle these entities automatically". You will need to create a new instance of the entity object, copy the values from the existing entity object, set the appropriate effective and expired dates on both objects, add the new entity object to the DbContext, then save changes. The best place to do this is by overriding the SaveChanges() method of your DbContext. To keep it as clean and manageable as possible, I suggest using the repository pattern.
I need to copy data from one database to another with EF. E.g. I have the following table relations: Forms->FormVersions->FormLayouts... We have different forms in both databases and we want to collect them to one DB. Basically I want to load Form object recursively from one DB and save it to another DB with all his references. Also I need to change IDs of the object and related objects if there are exists objects with the same ID in the second database.
Until now I have following code:
Form form = null;
using (var context = new FormEntities())
{
form = (from f in context.Forms
join fv in context.FormVersions on f.ID equals fv.FormID
where f.ID == 56
select f).First();
}
var context1 = new FormEntities("name=FormEntities1");
context1.AddObject("Forms", form);
context1.SaveChanges();
I'm receiving the error: "The EntityKey property can only be set when the current value of the property is null."
Can you help with implementation?
The simplest solution would be create copy of your Form (new object) and add that new object. Otherwise you can try:
Call context.Detach(form)
Set form's EntityKey to null
Call context1.AddObject(form)
I would first second E.J.'s answer. Assuming though that you are going to use Entity Framework, one of the main problem areas that you will face is relationship management. Your code should use the Include method to ensure that related objects are included in the results of a select operation. The join that you have will not have this effect.
http://msdn.microsoft.com/en-us/library/bb738708.aspx
Further, detaching an object will not automatically detach the related objects. You can detach them in the same way however the problem here is that as each object is detached, the relationships that it held to other objects within the context are broken.
Manually restoring the relationships may be an option for you however it may be worthwhile looking at EntityGraph. This framework allows you to define object graphs and then perform operations such as detach upon them. The entire graph is detached in a single operation with its relationships intact.
My experience with this framework has been in relation to RIA Services and Silverlight however I believe that these operations are also supported in .Net.
http://riaservicescontrib.codeplex.com/wikipage?title=EntityGraphs
Edit1: I just checked the EntityGraph docs and see that DetachEntityGraph is in the RIA specific layer which unfortunately rules it out as an option for you.
Edit2: Alex Jame's answer to the following question is a solution to your problem. Don't load the objects into the context to begin with - use the notracking option. That way you don't need to detach them which is what causes the problem.
Entity Framework - Detach and keep related object graph
If you are only doing a few records, Ladislav's suggestion will probably work, but if you are moving lots of data, you should/could consider doing this move in a stored procedure. The entire operation can be done at the server, with no need to move objects from the db server, to your front end and then back again. A single SP call would do it all.
The performance will be a lot better which may or may not not matter in your case.
I need to load an object from the database, modify some of its fields and relations, and then I want to store a new value for only one field, without modifying the rest.
It would look something like this:
var thing = db.Things.First();
thing.Field1 = "asdas";
thing.Field2 = 23;
thing.OtherThings.Add(new OtherThing());
thing.FieldToUpdate = doSomething(thing);
db.SaveChanges();
But that would save all the changes, what I want is to only save FieldToUpdate...
I've looked around and all I've found is to use stored procedures, which seems like too much for something that looks so simple, besides I would have to make a different stored procedure for each time I need to do something like this...
My current solution is to open another context, load the thing again, update the FieldToUpdate and SaveChanges, but that's both inefficient and ugly.
If you want to do this with attached entity you have to update FieldToUpdate FIRST and call SaveChanges. Than you can update other fields and call SaveChanges again if needed. No other way with attached entity.
Other way you can try is to detach entity, modify what you want to (it will not track changes). Then attach entity back to context and call:
// I suppose that db is ObjectContext or inherited type
db.ObjectStateManager.GetObjectStateEntry(thing).SetModifiedProperty("FieldToUpdate");
Now only FieldToUpdate is tracked as changed.
The Entity Framework is smart enough to figure out what has changed and what hasn't and optimizes the SQL statement is uses accordingly. If you only change FieldToUpdate, then the SQL statement will only be an update on the single field, not on everything.
However, if you do change Field1 and Field2 from what they were originally, they will be persisted too, but ONLY if they changed. Otherwise, there's no need to tell the DB to change it to what it already is.
Entity framework does it this way because that's exactly what the developer wants 99.9% of the time. If you are going to use an entity object as an object that you want to move around and manipulate in ways other than treating it as a model of the database (like it should be), then you may want to consider creating another new wrapper class that lets you mess with all the data fields that you want (and have others that aren't in there), and then have the save method of it do the proper entity framework persistance, to keep things separate and clean.
I have a detached set of client objects that I'd like to update (I know they already exist in the db by primary key). Now I want to update them to the database. Knowing I need to query them first, I do so and now have to basically take the properties from the deattached objects and apply them to the attached objects. I finally call save changes. Is there a slick way to apply these properties from the detached collection to the attached one?
NOTE: The detached objects don't have the primary keys in them but I do have enough information to link with via a comparer class.
You don't need to do what you're doing. You can just call the Attach method on your ObjectContext to tell it that you want to work with your detatched objects. Then just call SaveChanges to update the database with your changed objects.