如何使用.NET DbPropertyValues.SetValues仅设置选定的属性?

时间:2014-08-20 09:32:51

标签: c# .net entity-framework

我正在尝试编写一些代码,允许我使用Entity Framework更新分离的实体。 到目前为止,代码看起来像这样:

    public virtual void UpdateUnattached(T entity, string lookupPropertyName, string primaryKeyPropertyName)
    {
        if (entity == null)
        {
            throw new ArgumentException("Cannot update a null entity.");
        }

        // Get the data entry associated with the unattached entity from the context.
        var entry = DataContext.Entry<T>(entity);

        if (entry.State == EntityState.Detached)
        {
            // Get the already attached entity by the lookup property (which can be different from the primary key).
            var attachedEntity = this.dbSet.Local.SingleOrDefault(
                e => (int)ObjectUtil.GetPropertyValue(e, lookupPropertyName) == (int)ObjectUtil.GetPropertyValue(entity, lookupPropertyName)
            );

            // Get the value of the primary key for the attached entity.
            var primaryKeyValue = ObjectUtil.GetPropertyValue(attachedEntity, primaryKeyPropertyName);

            // Set the primary key of the unattached entity.
            ObjectUtil.SetPropertyValue(entity, primaryKeyPropertyName, primaryKeyValue);

            if (attachedEntity != null)
            {
                // Get the entry associated with the attached entity from the context and set the values of the unattached entity to be updated.
                var attachedEntry = DataContext.Entry(attachedEntity);
                attachedEntry.CurrentValues.SetValues(entity);
            }
            else
            {
                entry.State = EntityState.Modified;
            }
        }
    }

attachedEntry.CurrentValues.SetValues(entity);行上,我想设置某些属性的值并跳过其他属性。这将允许我通过传递我不想更新的属性的名称来使这种方法更通用。 有谁知道这是否可能? SetValues方法还有一个接受DbPropertyValues对象的重载,但我找不到构建此对象的方法,而没有我不想更新的属性。

2 个答案:

答案 0 :(得分:2)

当前值将设置所有标量属性。

如果您想要自定义映射,可以使用反射。

foreach (var name in propertyNames)
{
    var value = entity.GetType().GetProperty(name).GetValue(entity, null);
    attachedEntity.GetType().GetProperty(name).SetValue(attachedEntity, value);
}

答案 1 :(得分:2)

感谢。 我已经开始尝试使用反射...我最终用attachedEntry.CurrentValues.SetValues(entity);替换SetAttachedEntityValues(attachedEntity, entity, new string[] { "Payout", "Client", "Country" });调用,调用一个方法来复制除数组上指定的属性之外的所有属性:

    private void SetAttachedEntityValues(T attachedEntity, T entity, string[] excludePropertyNames)
    {
        var properties = typeof(T).GetProperties().Where(x => !excludePropertyNames.Contains(x.Name)).ToList();

        foreach(var property in properties)
        {
            var propertyValue = ObjectUtil.GetPropertyValue(entity, property.Name);
            ObjectUtil.SetPropertyValue(attachedEntity, property.Name, propertyValue);
        }
    }

ObjectUtil是一个类,其方法与Yuliam Chandra建议的方法非常相似。