在Linq到实体中推广CRUD测试

时间:2013-06-06 18:11:58

标签: c# linq-to-entities

我们有很多测试,例如:

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();
}

没有Asserts,因为除非抛出异常,否则将通过测试。

我想概括一下,而不是复制这段代码并改变一些细节。 唯一不同的位是

1)实体类型和相应的存储库(这里是DataFieldSet和DataFieldSetRepository) 2)新创建的实体的内容(通常是使测试通过的最小内容,此处标签和标题不能为空) 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()

调用The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.时失败了

我猜我的keyEqualsKey谓词与原始x => x.Id == entity.Id不完全相同。

有没有办法解决这个问题?

注释行//var keyProperties ...获取实体的所有关键属性。是否有动态方法来构建比较实体键的谓词,以便可以完全删除keyComparerkeyEqualsKey

0 个答案:

没有答案