如何翻译DbEntityEntry';将OriginalValues转换为强类型和分离的对象

本文关键字:转换 OriginalValues 强类型 对象 分离 何翻译 翻译 DbEntityEntry | 更新日期: 2023-09-27 18:21:21

我目前正在测试和修改我的api服务。主Update函数调用验证和事件处理程序,但在很大程度上依赖于DbEntityEntry。DbEntityEntry,或者更确切地说是其OriginalValues属性的问题在于,当访问实体不存在的属性时,它不会引发异常或警告编译器。正在搜索一个更健壮的类来将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它携带的数据是Item的数据。我会简单地使用OriginalValues.ToObject()并将其放置在一个实体上,但具有相同EntityKey的两个实体会使我对实体跟踪的熟悉程度有所提高。

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

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

如何翻译DbEntityEntry';将OriginalValues转换为强类型和分离的对象

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

构造函数的设计方式避开了DbPropertyValue的mocking不足。DbEntityPropertyValues有两个构造函数,一个采用单个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];
    }
}

欢迎批评和建议。