如何更新现有的断开实体

时间:2016-07-16 23:58:54

标签: entity-framework-core

我有这个代码在EntityFrameworkCore中工作。

public void SaveProject(Project item)
    {
        var existing = _context.Projects.FirstOrDefault(a => a.Id == item.Id);
        existing.Description = item.Description;
        existing.IsArchived = item.IsArchived;
        existing.IsDeleted = item.IsDeleted;
        existing.Name = item.Name;
        _context.SaveChanges();

    }

它接受一个断开连接的实体,在数据库中找到它并应用更改。

有更好的方法吗?

我想不打电话给数据库。换句话说,我希望能够将实体标记为已修改,然后调用SaveChanges()。

有办法吗?

3 个答案:

答案 0 :(得分:4)

如果您确定数据库中存在该项,则可以使用DbContext的Attach方法,如下所示

public void SaveProject(Project item)
{
    _context.Projects.Attach(item);
    _context.Entity(item).State=EntityState.Modified;
    _context.SaveChanges();
}

答案 1 :(得分:0)

在EntityFramework Core中,现在可以使用Update方法完成此操作:

 DbContext.Update<Item>(item);
 this.SaveChanges();

在2.1版中,如果Id属性是自动生成的,则Update方法现在可以用于新实体和现有实体。

The Docs

不利之处在于, all 属性被标记为已修改,即使它们相同。这样做的问题是,如果您要在数据库触发器中记录更改,则每个属性都将被标记为已更改,即使它们没有更改也是如此。如果只希望更新特定属性,则需要从数据库中获取实体,根据需要进行更新,然后保存。

答案 2 :(得分:0)

在通过主键找到断开连接的实体后,我创建了以下扩展方法以仅更新特定值(在updateAction中指定)。

场景:我有一个ASP Core页面,该页面在其视图中仅使用实体的一部分,并且通过不具有所有字段的DTO从Web层转移到Web层

public static T FindByPrimaryKey<T>(this DbContext context, T disconnectedEntity) where T : class
{
    var keyValues = context.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
        .Select(p => typeof(T).GetProperty(p.Name))
        .Select(p => p.GetValue(disconnectedEntity)).ToArray();

    var connectedEntity = context.Find<T>(keyValues);

    return connectedEntity;
}

public static void UpdateByPrimaryKey<T>(this DbContext context, T disconnectedEntity, Action<T> updateAction) where T : class
{
    var connectedEntity = context.FindByPrimaryKey(disconnectedEntity);

    updateAction(connectedEntity);
}