The goal is simple. I need to update the LastUpdated column in the Schedule table. I've tried several different methods to achieve that goal but with no success. I'm certain the code is pointing to the correct database and I'm also checking the correct [local] database for the changes. When a break point is set on SaveChanges(), the code halts at that point. I can see that "db" contains the updated Date/Time information for the correct record. Yet, it does not save it to the database.
Having gone through Stack Overflow, I've tried some suggestions like using Attach and setting the Entity State [to Modified]. Neither of those suggestions worked. HasChanges returns false, even though I can see the change is applied to the context variable.
Also, the class this method is in contains other methods that have no problem accessing the database and doing some inserts. The below code is just three different attempts to give you an idea on how I'm trying to do it. Any suggestions would be greatly appreciated.
public static void UpdateLastUpdated(int scheduleId)
{
using (var db = new MyContext())
{
var schedule = from s in db.Schedule where s.Id == scheduleId select s;
schedule.FirstOrDefault().LastUpdated = DateTime.Now;
db.SaveChanges();
var schedule2 = db.Schedule.Find(scheduleId);
schedule2.LastUpdated = DateTime.Now;;
db.SaveChanges();
var schedule3 = db.Schedule.Single(s => s.Id == scheduleId);
schedule3.LastUpdated = DateTime.Now;
db.SaveChanges();
}
}
You must indicate the change
db.Entry(schedule3).State = EntityState.Modified;
or
db.Entry(schedule3).Property(x => x.LastUpdated).IsModified = true;
So as it turns out, after a lot of trial and error... The issue was because the column was computed. I tried updating another column in the same table from that method and it worked fine. Then I did some research on computed columns and found that to be the problem. After removing the annotation, the code works fine. Now I just need to figure out how to get the default value set without the annotation.
Thank you to everyone who offered solutions and comments. Much appreciated!
Related
Sometimes I need Id of inserted entity. To achieve this, I use:
entity = await _repository.InsertAsync(entity);
With this, entity.Id is always 0. Because of this, I'm adding the line below.
await CurrentUnitOfWork.SaveChangesAsync();
If I add this line, I can get the Id. But, this way seems dirty to me. Is there another way? Or is this way already correct? I just want to be sure. I want to know that using CurrentUnitOfWork will not be cause problems that I may not know. Thank you.
There is InsertAndGetIdAsync for when you explicitly need the Id.
var entityId = await _repository.InsertAndGetIdAsync(entity);
If it's an Identity column from the db, where the id is automatically generated, you can't get the Id value until the row is stored in the DB.
This is why you need to do the SaveChangesAsync. Before you do that, the object is in-memory but not stored in the DB yet, which is where the Id will be assigned for that object.
I have 6 related tables. I am using a view model to show the properties from all 6 tables in my view. I am able to add data in single transaction using the above structure. But while editing the data I get - "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded." error message.
From the message it seems that the 0 rows were affected in some table. In my view it might be possible that not every value will be edited. Only some values belonging to some table will be edited and some will be stored as it is. So if the values from one table are not at all edited and if I try to do the following, then the above error pops up-
db.Entry(tbl).State = EntityState.Modified;
db.SaveChanges();
Is there a way to Modify the entity state of only those tables whose values are edited in the Edit View? Or is there any other better approach for this?
Please help. Thanks.
For a project here we did the following:
Perhaps an important one, is the Context.People.Attach() method.
Context.People.Attach(person);
// Disable validation otherwise you can't do a partial update
Context.Configuration.ValidateOnSaveEnabled = false;
Context.Entry(person).Property(x => x.AddressId).IsModified = true;
Context.Entry(person).Property(x => x.Birthday).IsModified = true;
Context.Entry(person).Property(x => x.Name).IsModified = true;
...
await Context.SaveChangesAsync();
Perhaps this is something you can work with? Not sure if the same approach can help for your case.
Example of editing an entity:
//Get the database entry
var entity = db.Person.First(c=>c.ID == 1);
//OR
//Attach a object to the context, see Nsevens answer.
db.Person.Attach(entity);
//Change a property
entity.Job = "Accountant";
//State it's a modified entry
db.Entry(entity).State = EntityState.Modified;
//Save
db.SaveChanges();
If you are editing multiple entries you will need to set every one to EntityState.Modifed, for example in a foreach loop.
Strange behavior on a code I'm trying to develop.
I'm not understanding if it is something with the DB / code / permissions.. or other.
What is happening is that after filling up a form, some specific values which should be 0 are being passed to the database as null. If I see directly on the database, they are set as null. One of the fields is an "int" and the other is a "boolean".
For this code I'm using C# with ASP.net and the Entity Framework. The database is Microsoft SQL.
What could be useful to try to find the issue here?
What could I be missing?
I've tried so far the following:
Changing settings on the database from accepting null values to not accept null values. With this when I try to save an object of this type, the object is not saved, as there are fields which are being passed as null. If I confirm with the debugger before the action to the Database, they are filled as 0 and not as null.
Tried to change the way the users are authenticated. No changes.
Rebuild the database with the previous settings. No changes.
Rebuild the solution with all the database connection. No changes.
Confirmed the methods / procedures to store and update the database, they seem to be correct.
Also, they work for the other fields in this object.
I've searched for some solutions here in stackoverflow and through the web, but until now, nothing has worked.
What else could I check to understand why the values reach the database as null?
The code:
string path = Server.MapPath("~/prod/ficheiros/") + uplFicheiro.FileName;
uplFicheiro.SaveAs(path);
videos v = new videos();
v.id = 21;
v.video_name = VideoName.Text;
v.desc = DescVideo.Text;
v.aprov = true; <--- reaches DB as null
v.username = Page.User.Identity.Name;
v.url = "45";
v.num_visualizacoes = 0; <--- reaches DB as null
AcessoDados.DBVideos.insertVideo(v);
GridView1.DataBind();
CleanForm();
The insertVideo:
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public static bool insertVideo(videos vid)
{
bool res = false;
try
{
contexto.Entry(vid).State = System.Data.Entity.EntityState.Added;
res = (contexto.SaveChanges() != 0);
}
catch (Exception) { }
return res;
}
I found the problem. The method which is writing on the database is not including the fields which I'm seeing as null. Hence the reason for them to reach the DB as null.
I need to correct this part which was generated by the Entity Model. Is there any way for the model to be corrected instead of I writing the methods manually?
-You need to go to properties for the colu
- check there General block -> Default Value and Binding
- make sure you set it to 0 (zero)
- If it is blank it will take by defaulf NULL
C# and general programming noobie here.
I have two tables. Property and Memo. There can be many Memo's to a single Property. I have, at least I think I do, the format of the object creation done correctly. The issue I do have is the Memo object doesn't save with the Property object. The Property object seems to save just fine.
Since I am a stack-noobie, I cannot post images strait into the post, so I've uploaded a couple which show both my Entities Diagram and the Referential Constraint dialogue.
www.jmtland.com/Pics/Diagram.png
www.jmtland.com/Pics/Referential%20Constraint.png
MTDBEntities1 dc = new MTDBEntities1();
Property newProp = new Property();
newProp.Address = t_Address.Text.Trim();
newProp.City = t_City.Text.Trim();
newProp.State = t_State.Text.Trim();
newProp.Zip = t_Zip.Text.ToString();
newProp.PropertyType = cb_PropertyType.Text.Trim();
if (t_SizeMin.Text.Trim().Length != 0) { newProp.SizeMin = Convert.ToInt64(t_SizeMin.Text); } // SizeMin is not required, so it won't be passed to the DB if there is no value.
newProp.SizeMax = Convert.ToInt64(t_SizeMax.Text);
newProp.SizeMetric = cb_SizeType.Text.Trim();
if (t_PriceMin.Text.Trim().Length != 0) { newProp.PriceMin = Convert.ToDecimal(t_PriceMin.Text); } // PriceMin is not required, so it won't be passed to the DB if there is no value.
newProp.PriceMax = Convert.ToDecimal(t_PriceMax.Text);
newProp.LeaseType = cb_LeaseType.Text.Trim();
newProp.WebLink = t_WebLink.Text.Trim();
newProp.Deleted = false;
newProp.DateDeleted = null;
newProp.DateCreated = DateTime.Now;
Memo newMemo = new Memo();
newMemo.Memo1 = t_PropertyMemo.Text.Trim();
newMemo.MemoDateCreated = DateTime.Now;
newProp.Memos.Add(newMemo);
dc.AddToProperties(newProp);
dc.SaveChanges();
I've been searching around for a fix for this problem for the last two days on multiple forums. I've followed so many examples that I almost forgot my original code.
Sorry for the noobness.
Update:
I have tried saving the Property Table first, then the Memo table.
-Doesn't work either.
I have run through the debugger and there seems to be data associated with the Memo object as well as the Property object contains the Memo object in question but it, for some reason, doesn't save at the same time.
I've though about a different way around it, where I could save the property, then do a new query to get the PropertID of that new object, then force save the Memo object with the PropertyID returned.
The issue I have with that method is that would mean my understanding of the Entity framework wouldn't be correct. I'd probably be able to hack my way around it but if I can't get it to work properly from the beginning, I fear that my later implementation of the same tech will be hindered by my inability to get it right from the get go. I've dabbled in programming before and the one thing I've learned is if you don't learn the basics right the first time, the rest of your experience can be corrupted.
The comment from RPM1984 seems to have worked. I don't know why that worked over what I tried but whatever, I can now move onto my next 4 hour block of programming a single method!
Do you have a navigational property
called "Memos" on the "Property"
entity on your EDMX? I think the last
line should be
dc.Properties.AddObject(newProp) –
RPM1984 5 hours ago
I wasted the better part of the day on this and am no closer to a understanding the issue than what I was this morning.
I am looping through a set of objects and marking them for deletion. The 2nd one always causes the above exception. tb_invoice has a FK to tb_shipment.
As always, I am probably missing something very obvious, but I have stripped out so much from this code already that there is nothing left, and I am still getting this exception. This is a local SQL 2008 instance and there is of course nothing and nobody changing the invoice in between reading them and calling SubmitChanges(). Help!
myDataContext db = new myDataContext();
IQueryable<invoiceDetail> pendingInvoices
= db.GetInvoiceDetailPending();
foreach (invoiceDetail id in pendingInvoices) {
tb_shipment s = db.GetShipmentById((Guid)id.shipment_id);
db.tb_invoices.DeleteOnSubmit(
db.GetInvoiceById(s.tb_invoices.FirstOrDefault().id)); }
SubmitChanges(); // fails for the 2nd invoice
}
System.Data.Linq.ChangeConflictException: Row not found or changed
Setting the Delete action for the foreign keys in SQL Server to "Cascade" did the same. I wish I had remembered earlier that I ran into this before.