I know you can do Model.delete() and Model.save()
Is there a way to update an existing row?
In Fluent 2.0 there is a property added to every Entity/Model:
let storage = Storage()
This object is holding additional information for each entity, if storage.exists is true it will update data when you call save() instead of trying to insert new item to database.
Reading Fluent's code, I believe it saves the fields that are "dirty".
So, you would have to do something like this:
let user = try User.find(42)
user.name = "Other Name"
try user.save()
I didn't try this, but I'll do it soon.
Related
ormlite-android-4.29, ormlite-core-4.29
I have a ForiegnCollection of PantryCheckLine objects like this in my PantryCheck class.
#ForeignCollectionField(eager = true, maxEagerForeignCollectionLevel = 1)
private ForeignCollection<PantryCheckLine> pantryCheckLines;
Let's say I had 3 PantryCheckLines objects and I deleted one. Then I want to delete the PantryCheck with combined PantryCheckLines of it. Everything seems working. But the size of the ForiegnCollectionis not correct.
deleting method as follows.
PantryCheckLineRepo pantryCheckLineRepo =
new PantryCheckLineRepo(DaoFactory.getPantryCheckLineDaoInstance());
Collection<PantryCheckLine> pantryCheckLinesCollection =
this.getPantryCheckLines();
Log.v("pantrychecklines size", pantryCheckLinesCollection.size());
pantryCheckLineRepo.delete(pantryCheckLinesCollection);
Log.v("pantrychecklines", "deleted");
appreciate your help.
I can't answer specifically because I'm not sure what the delete() method is doing. If you edit your question with more details about what Dao calls or ForeignCollection calls are being made, I can add details here.
The only way the collection size would be affected is if you used the remove(Object) method on the collection itself. If you used the Dao to delete the item behind the scenes then the collection would not know that the delete happened and its eager fetched internal list size would not be affected. The lazy collections (eager = false) always go to the database so either remove(Object) or dao.delete(Object) would work.
Hope this helps.
I have following code to add or update the Entity object. finding the object by primary key, based on the response I am adding or updating the object.
Adding record works, but during update its giving this error message "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key"
In my MSSQL database I have only one record.
var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
db.Envelopes.Add(model);
db.SaveChanges();
ViewBag.status = "Record Add successfully";
ModelState.Clear();
}
else
{
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
}
How can I fix this error message?
As mentioned by #anon you can't attach model once you loaded the entity with the same key. The changes must be applied to attached entity. Instead of this:
db.Entry(model).State = EntityState.Modified;
use this:
db.Entry(v).CurrentValues.SetValues(model);
If an earlier query read the entity to be updated and that's why you're getting the error, you can change that query to AsNoTracking. See the AsNoTracking example in:
http://www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application
I assume you are saying that your error occurs here:
db.Entry(model).State = EntityState.Modified;
Once you execute Find(), your Envelope is already being tracked by your context. This means that if you need to change a property, just change it on v, and then call SaveChanges(). Don't worry about setting the state to Modified.
If you set your context to AsNoTracking() this will stop aspmvc tracking the changes to the entity in memory (which is what you want anyway on the web). Don't forget the using statement.
using System.Data.Entity;
db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);
I got this from this forum post ->
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application
I'm using this because I have already created a new instance, and populated the properties I need to update.
var key=this.CreateEntityKey("Envelopes",model);
ObjectStateEntry ose;
if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
var entity=(Page)ose.Entity;
Envelopes.Detach(entity);
}
this.Envelopes.Attach(model);
And another approach to solve the issue is detaching tracked entity and re-attaching the modified one. See my solution here.
I use JPA 2.0 for my project.
I delete and entity and then try to persist same data but it throws :
org.hibernate.ObjectDeletedException: deleted instance passed to merge .
Below is what I am performing :
for(Education edu : educations) {
entManager.remove(edu);
Education tempEdu = new Education();
tempEdu.setCourse(edu.getCourse());
tempEdu.setInstitution(edu.getInstitution());
tempEdu.setPlace(edu.getPlace());
tempEdu.setFromDate(edu.getFromDate());
tempEdu.setToDate(edu.getToDate());
tempEdu.setMember(updatedMem);
entManager.merge(tempEdu);
}
Can you tell me how to remove an entity and then persist its data in another entity?
Regards,
Satya
I think the remove operation cascades to some of the relationships, which you are using later:
tempEdu.setCourse(edu.getCourse());
tempEdu.setInstitution(edu.getInstitution());
tempEdu.setPlace(edu.getPlace());
Try commenting these line and see whether it works. If so, you must either remove cascading on this relationships or create copy of of this objects just as you are doing it with tempEdu.
And this leads to the question already asked by axtavt - what are you trying to achieve? You'll end up deleting bunch of objects and then recreating them and saving back...
As posted by you in comments - If any entity is deleted/edited/added in UI, I delete all related entities and then recreate the ones which come from UI ...
Maintain two lists, one for entities in database & another for UI.
//---
dbEntries.removeAll(uiEntries); // dbEntries will have entities to be deleted
for(Education edu : dbEntries){
em.remove(edu); // Deleting entries not found in UI
}
for(Education edu : uiEntries){
em.merge(edu); // Updating existing entity else persisting new one
}
//---
This way you can achieve what you are trying so far, point out if I got it wrong.
Else in your code, try merging tempEdu before removing edu.
I'm trying to update a POCO object using entity framework in the following way:
context.Jobs.Attach(job);
context.SaveChanges();
That does not work. No error is thrown, it just isn't updating the values in the database.
I tried:
context.Jobs.AttachTo("Jobs", job);
context.SaveChanges();
Nothing wrongs, still no error and no updates.
What about changing the ObjectState?
context.ObjectStateManager.ChangeObjectState(job, System.Data.EntityState.Modified);
From MSDN: ObjectStateManager.ChangeObjectState Method.
I guess you are working with detached object - check second part of this answer.
another reason that this may not work is when the corresponding Jobs.cs file has been committed but the .edmx file has not. This means that the property is present but not mapped and therefore EF does not consider the object modified. For example:
...
using (var dao = new DbContext())
{
dao.Jobs.Attach(job);
job.SomeProperty = 1234; // SomeProperty exists but is not in the .edmx
dao.SaveChanges();
}
if SomeProperty is present in Jobs.cs but missing from the .edmx file, this code will compile and execute without a hint that anything is wrong but SomeProperty will not be updated in the Database. Took me the best part of a day to find this one.
you have to get the job first then you could successfully update it, chk below snippet
var job = context.Jobs.Where(p => p.Id == id).FirstOrDefault();
//apply your changes
job.Title = "XXXX";
///....
context.SaveChanges();
My issue was that I was attaching after I updated the object, when in-fact, you have to attach BEFORE you update any properties
context.Table.Attach(object);
object.MyProperty = "new value";
context.Table.SaveChanges();
I have a Recommendation object and a FeedbackLevel object and the FeedbackLevel object is a navigation property inside a Recommendation object
Recommendation
int EntityKey;
FeedbackLevel Level;
Inserting a new one works just fine with AddObject(). Here's what I'm trying with the update, which doesn't work.
recommendation.Level = myRepository.GetFeedbackLevel(newLevel);
_context.Recommendations.Attach(new Recommendation { EntityKey = recommendation.EntityKey });
_context.Recommendations.ApplyCurrentValues(recommendation);
_context.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);
The code above is basically a compact version of what I have. Updating a scalar property works just fine, but I can't update a new navigation property as the avove code succeeds without any changes!
I've also tried a few other methods like getting an existing Recommendation first and then re-assigning the FeedbackLevel to it without any luck.
UPDATE:
Here is what I captured from the sql profiler during the save call:
exec sp_executesql N'update [dbo].[Recommendation]
set [FeedbackComment] = #0, [LastUpdatedDate] = #1
where ([RecommendationKey] = #2)
',N'#0 varchar(255),#1 datetime,#2 int',#0='This is cool',#1='2010-01-08 10:06:06.5400000',#2=11
It looks like it does not even know that the FeedbackLevel needs to be saved. How can I get it to trigger it?
Not sure exactly what your trying to do here,
but if your trying to do an update, simple way is to
1) do a, GET [entityName] by id, use include to get any child properties
2) update the attributes
3) make sure the entity state is modified
4) Save changes
By doing a GET first, you wont need to get attach it to the context before you update, as it will be already in there.