使用实体框架

时间:2017-02-07 18:31:55

标签: c# asp.net-mvc entity-framework repository-pattern

我正在尝试找到一种可以实现的模式,以便快速允许使用Entity Framework对实体进行部分更新。当我拥有完整的对象时,我可以使用Attach,但如果我只进行部分更新,我想找到一种方法以可重复的方式执行它,而不是每次都指定更改的属性。

我找到了this idea,并且非常喜欢它,但我很难让“OriginalValues”和“CurrentValues”变得不同,它们总是匹配。我应该如何检索实体以使这样的更新方法起作用?

我检索数据并使用它来填充页面上的信息(但用户可以只更改/查看实体的一部分),所以我只返回回发后的部分实体信息 - 我是否必须检索并在更新之前分离实体?我不能使用Try / UpdateModel,因为我不是在控制器中做这项工作。任何想法或替代模式将不胜感激。

public virtual void Update(T entity, params Expression<Func<T, object>>[] updatedProperties)
{
    //Ensure only modified fields are updated.
    var dbEntityEntry = DbContext.Entry(entity);
    if (updatedProperties.Any())
    {
        //update explicitly mentioned properties
        foreach (var property in updatedProperties)
        {
            dbEntityEntry.Property(property).IsModified = true;
        }
    }
    else
    {
        //no items mentioned, so find out the updated entries
        foreach (var property in dbEntityEntry.OriginalValues.PropertyNames)
        {
            var original = dbEntityEntry.OriginalValues.GetValue<object>(property);
            var current = dbEntityEntry.CurrentValues.GetValue<object>(property);
            if (original != null && !original.Equals(current))
                dbEntityEntry.Property(property).IsModified = true;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

看起来这可能是一个重复的问题。我找到了答案here

要将更新的属性与数据库中的值进行比较,必须从数据库重新加载文档。一个例子:

public ActionResult Edit(Document document, bool sendEmail, string commentsTextBox)
    {
        if (ModelState.IsValid)
        {
            var documentInDB = docsDB.Documents.Single(d => d.Id == document.Id);

            docsDB.Entry(documentInDB).CurrentValues.SetValues(document);

            foreach (string propertyName in docsDB.Entry(documentInDB)
                                            .OriginalValues.PropertyNames)
            {
                var OriginalValue = docsDB.Entry(documentInDB)
                                    .OriginalValues.GetValue<object>(propertyName);
                var NewValue = docsDB.Entry(documentInDB)
                               .CurrentValues.GetValue<object>(propertyName);

                if (!OriginalValue.Equals(NewValue))
                {
                    //capture the changes
                }
            }
        }
    }

显然,在我想要完成的业务层中实现,你必须将数据库版本和更新版本都传递给比较的方法。

一旦我测试过并且有一个工作样本,我就会更新代码。