4

I have a method for updating some tables. For update I need get first of TestProcess, but I don't like that. How can I update TestProcess without select(firstOrDefault) operation, used only for the update operation?

Example of method:

public void UpdateTestProcess(int id, string updateID)
{
    using (TestEntities context = new TestEntities())
                {
                    TestProcess pr = context.TestProcess.FirstOrDefault(x => x.MyID == id);
                    pr.UpdateID = updateID;             

                    context.TestProcess.Attach(pr);
                    context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified);
                    context.SaveChanges();
               }
}
3
  • what? To update an item you first have to 'get' it to apply the updates. Why don't you like that? Commented Jul 2, 2013 at 13:42
  • Probably because it is an extra query to the database Commented Jul 2, 2013 at 13:47
  • possible duplicate of Can I update an EF Entity without querying for it first? Commented Jul 2, 2013 at 13:48

3 Answers 3

7
TestProcess pr = new TestProcess()
{
    MyID == id,
};

context.Set<TestProcess>().Attach(pr);

pr.UpdateID = updateID;

context.SaveChanges();

If you are setting the value to the default value of that type (for example, setting an int to 0) it won't be picked up as a change, and you need to manually set the state.

pr.UpdateID = updateID;
context.Entry(pr).Property(p => p.UpdateID).IsModified = true;

You can put such code away in extension methods, so you can do things like this (I'll leave the implementation as an exercise):

Foo entity = this.DbContext.GetEntityForUpdate<Foo>(
    item => item.ID, model.ID
    );

this.DbContext.UpdateProperty(entity, item => item.Name, model.Name);
Sign up to request clarification or add additional context in comments.

5 Comments

How implement your example if I used ObjectContext?
Why would you use ObjectContext with EF 5 ?
I can't help you in that case. DbContext has been recommended for a while now, if the situation allows it, you should use that instead.
In your example MyID is a primary key. I need update not only by primary key, a need update also by foreign key. If I used you example with TestProcess pr = new TestProcess() { ForeignKey = id }; and pr.UpdateID = updateID; context.Entry(pr).Property(p => p.UpdateID).IsModified = true; after that I have error Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entrie. Whether I can update by foreign key?
I don't believe EF is capable of doing such an update without being supplied the primary key.
2

You can do like that (you probably should have all the test process data):

TestProcess pr = new TestProcess();

pr.Id = id;
pr.UpdateID = updateID;

context.Attach(pr);
context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified);
context.SaveChanges();

2 Comments

It is not work. I have error: Argument 1: cannot convert from 'Process' to 'System.Data.Objects.DataClasses.IEntityWithKey'
I'm trying context.AttachTo("TestProcesses", pr); context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified); context.TestProcesses.MergeOption = MergeOption.OverwriteChanges; context.AcceptAllChanges(); But not save changes
1

The code:

TestProcess testprocess = dbcontext.TestProcesses.Attach(new TestProcess { MyID = id });
tp.UpdateID = updateID;
dbcontext.Entry<TestProcess>(testprocess).Property(tp => tp.UpdateID).IsModified = true;
dbcontext.Configuration.ValidateOnSaveEnabled = false;
dbcontext.SaveChanges();

The result TSQL:

exec sp_executesql N'UPDATE [dbo].[TestProcesses]
SET [UpdateID] = @0
WHERE ([MyID] = @1)
',N'@0 bigint,@1 bigint',@0=2,@1=1

Note:

The "IsModified = true" line, is needed because when you create the new TestProcess object (only with the MyID property populated) all the other properties has their default values (0, null, etc). If you want to update the DB with a "default value", the change will not be detected by entity framework, and then DB will not be updated.

In example:

testprocess.UpdateID = null;

will not work without the line "IsModified = true", because the property UpdateID, is already null when you created the empty TestProcess object, you needs to say to EF that this column must be updated, and this is the purpose of this line.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.