Pergunta

I am using EF 4.3, VS 2010, .net 4.0. After google sometime, I did not get the answer, maybe most answers are for EF 5 and above.

I use db first to demo this question. The database sql:

CREATE TABLE [dbo].[T](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_t] PRIMARY KEY CLUSTERED
First I tried add new, like this:
private void btnAdd_Click(object sender, EventArgs e)
{
    T t = new T();
    t.ID = 1;
    t.Name = "a";
    TestDBEntities en = new TestDBEntities();
    //works no matter what the ID is,
    //and this is good
    en.AddToT(t);
    en.SaveChanges();
    MessageBox.Show("add");
}

Then tried update, my main goal is to pass an entity object, and directly update the entity with the same ID in database. If I copy the fields one by one, that will be OK. But if the entity has many fields(Here only 'Name' for demo), it will be time costing to write and maintain.

private void btnUpdate_Click(object sender, EventArgs e)
{
    T t = new T();
    t.ID = 1;
    t.Name = "a";
    TestDBEntities en = new TestDBEntities();

    var old = en.T.First(m => m.ID == 1);
    //An object with the same key already exists in the ObjectStateManager. 
    //The ObjectStateManager cannot track multiple objects with the same key.
    en.T.Attach(t);
    en.ObjectStateManager.ChangeObjectState(old, System.Data.EntityState.Modified);

    en.SaveChanges();
    MessageBox.Show("Update");
}
Foi útil?

Solução

Unfortunately, the DbContext.Entry method that allows you to attach the object to back to the DbContext, was added in EF5+.

As @Nilesh mentioned, for easy model binding without copying each property you should use a tool like AutoMapper or ValueInjecter.

With AutoMapper for example, you will simply do that:

private void btnUpdate_Click(object sender, EventArgs e)
{
    TModel t = new TModel();
    t.ID = 1;
    t.Name = "a";

    TestDBEntities en = new TestDBEntities();

    var entity = en.T.First(m => m.ID == 1);

    Mapper.Map<TModel, T>(t, entity);

    en.SaveChanges();
    MessageBox.Show("Update");
}

In case a more complex mapping is required, you can configure the mapping with Mapper.CreateMap method. Check the documentation for more examples.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top