【问题标题】:EF4.x: Updating using detached entity without copying fields one by oneEF4.x:使用分离实体进行更新,无需一一复制字段
【发布时间】:2026-01-04 14:20:06
【问题描述】:

我正在使用 EF 4.3、VS 2010、.net 4.0。 google了一段时间后,我没有得到答案,也许大多数答案都是针对EF 5及以上的。

我先用db来演示这个问题。数据库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");
}

然后尝试更新,我的主要目标是传递一个实体对象,并直接更新数据库中具有相同ID的实体。如果我一个一个地复制这些字段,那就可以了。但是,如果实体有许多字段(此处仅为演示的“名称”),编写和维护将耗费时间。

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");
}

【问题讨论】:

  • 您可以使用 AutoMapper 等工具将所有属性从一个实体映射到另一个实体。现在的问题是,据我所知,.net 4.0 中没有用于 asp.net Web 表单应用程序的模型绑定器。我发现本教程适用于 .net 4.5,其中在 Web 表单应用程序中引入了模型绑定。可能是this 帮助。您还可以编写自己的辅助实用程序,它将接受 POST 参数并将它们绑定到Type。或者可以在谷歌上搜索。

标签: c# linq entity-framework poco


【解决方案1】:

不幸的是,EF5+ 中添加了DbContext.Entry 方法,该方法允许您将对象附加回 DbContext。

正如@Nilesh 提到的,为了在不复制每个属性的情况下轻松进行模型绑定,您应该使用AutoMapperValueInjecter 之类的工具。

以 AutoMapper 为例,您只需这样做:

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");
}

如果需要更复杂的映射,您可以使用Mapper.CreateMap 方法配置映射。查看文档以获取更多示例。

【讨论】:

  • 谢谢,我也搜了db.Entry,不存在!
最近更新 更多