我们有很多这样的测试:
using (new TransactionScope())
{
var repository = _unitOfWork.DataFieldSetRepository;
var entity = new DataFieldSet {Label = "test", Title = "test"};
repository.Add(entity);
_unitOfWork.Commit();
entity = repository.GetAll().Single(x => x.Id == entity.Id);
entity.IsClosed = true;
repository.Update(entity);
_unitOfWork.Commit();
repository.Delete(entity);
_unitOfWork.Commit();
}
没有断言,因为除非抛出异常,否则测试通过。
我不想复制此代码并更改一些细节,而是想对其进行概括。唯一不同的位是
1)实体类型和对应的存储库(这里是DataFieldSet和DataFieldSetRepository) 2)新创建的实体的内容(通常是使测试通过的最小内容,这里Label和Title不能为空) 3)更新操作(通常是只有一个随机属性的值发生了变化)
到目前为止,我有这个:
public void AssertCrudOperationsWork<T>(T entity, Func<T, T, bool> keyComparer, Action<T> updateAction) where T : class
{
using (new TransactionScope())
{
var repository = (IRepository<T>)_unitOfWork.GetType().GetProperty(typeof(T).Name + "Repository").GetValue(_unitOfWork);
repository.Add(entity);
_unitOfWork.Commit();
//var keyProperties = typeof(T).GetProperties().Where(prop => prop.IsDefined(typeof(KeyAttribute), false));
Expression<Func<T, bool>> keyEqualsKey = x => keyComparer(x, entity);
entity = repository.GetAll().Single(keyEqualsKey);
updateAction(entity);
repository.Update(entity);
_unitOfWork.Commit();
repository.Delete(entity);
_unitOfWork.Commit();
}
}
[TestMethod]
public void CRUDTest_DataFieldGroup()
{
AssertCrudOperationsWork(new DataFieldSet {Label = "test", Title = "test"}, (a, b) => a.Id == b.Id, x => x.IsClosed = true);
}
问题是,它在调用Single()
with 时失败:The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
我想我的keyEqualsKey
谓词与原来的不完全相同x => x.Id == entity.Id
。
有没有办法来解决这个问题?
注释行//var keyProperties ...
获取实体的所有关键属性。是否有一种动态方法来构建比较实体键的谓词,以便可以完全删除thekeyComparer
和 the ?keyEqualsKey