EntityFramework 更新部分模型

17

我正在开发一个采用仓储模式和实体框架的MVC项目,现在我的表单上有一个示例模型。

示例模型:
1) 姓名
2) 年龄
3) 地址
4) 注释
5) 最后更新时间

我只显示编辑表单上列出的以下数据
1) 姓名
2) 年龄
3) 地址

现在,如果我使用仓储更新缺少属性值的模型,注释和最后更新时间字段将变为空。

我的问题是如何使用仓储更新仅选定的几个属性(不可用于仓储的TryUpdateModel方法),而且我不想调用原始对象并映射更新后的模型的属性。

是否有任何方法可以实现这一点?肯定有。

2个回答

24

您可以仅更新一部分字段:

using (var context = new YourDbContext())
{
    context.SamepleModels.Attach(sampleModel);

    DbEntityEntry<SameplModel> entry = context.Entry(sampleModel);
    entry.Property(e => e.Name).IsModified = true;
    entry.Property(e => e.Age).IsModified = true;
    entry.Property(e => e.Address).IsModified = true;   

    context.SaveChanges();
}

或者使用 ObjectContext API:

using (var context = new YourObjectContext())
{
    context.SamepleModels.Attach(sampleModel);

    ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(sampleModel);
    entry.SetModifiedProperty("Name");
    entry.SetModifiedProperty("Age");
    entry.SetModifiedProperty("Address"); 

    context.SaveChanges();
}

哦,好的,或者写一个 SQL 查询来更新,对吧?或者写一个通用的帮助程序来标记已编辑的属性,嗯...这就是 TryUpdate 应该在做的事情。 - Milan
EF 4.0 中不存在 Entry()。 - Suncat2000
1
@Suncat2000:第二个示例适用于EF 4.0,第一个示例适用于EF 4.1及更高版本。 - Ladislav Mrnka
1
如何在不重新编译的情况下更改此方法以更新不同的属性? - BILL
1
我想补充一点,为了最大限度地发挥这种方法的优势,您需要通过<yourDbConetxt> .Configuration.ValidateOnSave = false在上下文级别禁用模型验证。从技术上讲,您可以通过在模型中放入“虚拟数据”来确保模型满足模型状态验证 - 如果您不将这些属性设置为已修改,则不会将其发送到SQL,但我建议不要采用这种方法。 - Forest

3

这是一个旧的帖子,但如果有人感兴趣,在Ladislav的解决方案基础上,我们为EF 4.1及更高版本开发了一个有用的扩展方法:

public static void SetModified<TEntity>(
        this DbEntityEntry<TEntity> entry,
        IEnumerable<Expression<Func<TEntity, object>>> expressions) where TEntity : class, IEntity
    {
        foreach (var expression in expressions)
            entry.Property(expression).IsModified = true;
    }

显然,如果您的POCOs没有使用同名接口,您需要移除IEntity约束。

示例用法如下:

        var user = new User
        {
            Id = Request.Id,
            UserName = Request.UserName,
            FirstName = Request.FirstName
        };

        var expressions = new List<Expression<Func<User, object>>> 
                 { 
                     x => x.UserName, 
                     x => x.FirstName
                 };

        context.Entry(user).SetModified(expressions);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接