What steps to get rid of Collection was modified; enumeration operation may not execute. Error?

最后都变了- 提交于 2019-12-05 08:16:33

I had this problem as well but not iterating over the collection isn't really an option for me. After some thought, I did figure out a solution. The issue is that the mock sets up the various IQueryable properties off of a fixed IQueryable object from the original list. That causes any modification of that list to invalidate the corresponding IQueryable. The solution is to get a new IQueryable on each access using a lambda with Moq.

Here's the helper function I created to make mocking out DBSets easier, using the described technique.

public static Mock<DbSet<T>> MockDbSet<T>(List<T> list) where T : class
{
    var mockSet = new Mock<DbSet<T>>();
    mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(() => list.AsQueryable().Provider);
    mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(() => list.AsQueryable().Expression);
    mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(() => list.AsQueryable().ElementType);
    mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => list.GetEnumerator());
    mockSet.Setup(m => m.Add(It.IsAny<T>())).Callback((T x) => list.Add(x));
    mockSet.Setup(m => m.AddRange(It.IsAny<IEnumerable<T>>())).Callback((IEnumerable<T> x) => list.AddRange(x));
    mockSet.Setup(m => m.Remove(It.IsAny<T>())).Callback((T x) => list.Remove(x));
    mockSet.Setup(m => m.RemoveRange(It.IsAny<IEnumerable<T>>())).Callback((IEnumerable<T> x) => list.RemoveAll(x.Contains));
    return mockSet;
}

Edit: Added AddRange, Remove, RemoveRange since why not...

Edit 2: Correction for RemoveRange

I found a really Clumsy Solution:

        List<TEntity> tempList = new List<TEntity>();

        for (int i = query.Count() - 1; i >= 0; i--)
        {
            tempList.Add(query.ElementAt(i));
        }

        List<TEntity> resultsAsList = tempList.ToList();

       var results = resultsAsList.AsQueryable();

In the aforementioned code, it is important to use a for loop with an index to go through the DBSet instance. Furthermore, in the loop, you add each element to a List. ( Basically, it's important to Avoid using the Iterator)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!