我目前正在测试和修改我的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有什么替代方法?它还应该能够与其修改后的实体共存。
感谢您的时间和耐心,因为我正致力于重建对强类型语言的理解。
答案 0 :(得分:0)
我需要快速继续工作,所以我想出了一个体面但不太理想的解决方案。我创建了一个类,它本质上是DbPropertyValues的包装器,名为DbEntityPropertyValues,它接受一个类型参数。调用GetValue时,它使用反射(bleh)来检查EntityType是否具有给定属性。与DbPropertyValues不同,如果属性不存在,则会抛出错误。这在运行时不是很有用,但它会在测试期间更容易地清除问题。
构造函数的设计方式绕过了DbPropertyValue的模拟不足。 DbEntityPropertyValues有两个构造函数,一个接受一个DbPropertyValue,一个接受一个实体。在正常操作期间将使用DbProperyValue,在模拟期间将使用实体。这是代码。
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];
}
}
欢迎提出批评和建议。