C# 如何将DbEntityEntry的原始值转换为强类型和分离的对象?

C# 如何将DbEntityEntry的原始值转换为强类型和分离的对象?,c#,entity-framework,validation,C#,Entity Framework,Validation,我目前正在测试和修改我的api服务。主更新函数调用验证和事件处理程序,但严重依赖DbEntityEntry。DbEntityEntry,或者更准确地说,它的OriginalValues属性的问题在于,在访问实体的不存在属性时,它不会引发异常或警告编译器。我们正在寻找一个更健壮的类来转换原始值,但我的结果是空的 以下是我开始的内容: public override Item Update(Item revisedItem, DbContext context) { DbEntityEntr

我目前正在测试和修改我的api服务。主更新函数调用验证和事件处理程序,但严重依赖DbEntityEntry。DbEntityEntry,或者更准确地说,它的OriginalValues属性的问题在于,在访问实体的不存在属性时,它不会引发异常或警告编译器。我们正在寻找一个更健壮的类来转换原始值,但我的结果是空的

以下是我开始的内容:

public override Item Update(Item revisedItem, DbContext context) {
    DbEntityEntry entry = context.Entry<Item>(revisedItem);
    DbPropertyValues originalValues = entry.OriginalValues;
    ...
    validateType(revisedItem.Type, entry.OriginalValues.GetValue<Nullable<decimal>>("Tipe"));  //GetValue won't catch the misspelling of "Type"
    ...
    return revisedItem; 
}
这很麻烦,因为我突然不得不测试以确保OriginalValues返回我期望的值,以防止输入错误。我非常愿意告诉DbPropertyValues,它所携带的数据是一个项目的数据。我会简单地使用OriginalValues.ToObject并将其放置在一个实体上,但拥有两个相同EntityKey的实体会使我对实体跟踪的熟悉程度变得复杂

使用不使用反射的原始值的替代方法是什么?它还应该能够与其修改后的实体共存


感谢您的时间和耐心,因为我正在努力重建我对强类型语言的理解。

我需要快速继续工作,所以我想出了一个不错但不太理想的解决方案。我创建了一个类,它本质上是DbPropertyValues的包装器,称为DbEntityPropertyValues,它接受一个类型参数。调用GetValue时,它使用反射bleh检查EntityType是否具有给定的属性。与DbPropertyValues不同,如果属性不存在,它将抛出错误。这在运行时不是很有用,但在测试期间它将更容易地消除问题

构造函数的设计方式绕过了DbPropertyValue的模拟不足。DbEntityPropertyValue有两个构造函数,一个接受单个DbPropertyValue,另一个接受实体。DbPropertyValue将在正常操作期间使用,实体将在模拟期间使用。这是代码

public class DbEntityPropertyValues<EntityType> where EntityType : MyEntity {

    private readonly Dictionary<string, object> entityKeyValuePairs = new Dictionary<string, object>();

    public DbEntityPropertyValues (DbPropertyValues dbPropertyValues) {
        IEnumerable<string> dbPropertyNames = dbPropertyValues.PropertyNames;

        foreach(var prop in dbPropertyNames) {
            entityKeyValuePairs.Add(prop, dbPropertyValues.GetValue<Object>(prop));
        }
    }

    //Intended only for testing.
    //A detached entity gets passed in instead of DbPropertyValues which can't be mocked.
    public DbEntityPropertyValues (CompanyEntity entity) {
        IEnumerable<PropertyInfo> entityProperties = typeof(EntityType).GetProperties().AsEnumerable();

        foreach (var prop in entityProperties) {
            entityKeyValuePairs.Add(prop.Name, entity.GetType().GetProperty(prop.Name).GetValue(entity, null));
        }
    }

    public T GetValue<T> (string propertyName) {
        if (!typeof(T).Equals(typeof(EntityType).GetProperty(propertyName).PropertyType)) {
            throw new ArgumentException(String.Format("{0} of type {1} does not exist on entity {2}", propertyName, typeof(T), typeof(EntityType)));
        }

        return (T)entityKeyValuePairs[propertyName];
    }
}
欢迎批评和建议