C# 模拟数据库上下文上为空的查询实体关系

C# 模拟数据库上下文上为空的查询实体关系,c#,entity-framework,unit-testing,mocking,moq,C#,Entity Framework,Unit Testing,Mocking,Moq,我使用的是模拟DbContext。我在查询空的IOrderedQueryable时遇到问题 var report = new Report(); report.DataSource = null; var q = context.Reports.Select(x => x.DataSource).OrderBy(x => x.Name); var results = q.ToList(); 当我调用ToList时,它在此行的testdbasynumerator.MoveNextAs

我使用的是模拟
DbContext
。我在查询空的
IOrderedQueryable
时遇到问题

var report = new Report();
report.DataSource = null;
var q = context.Reports.Select(x => x.DataSource).OrderBy(x => x.Name);
var results = q.ToList();
当我调用
ToList
时,它在此行的
testdbasynumerator.MoveNextAsync
中抛出一个错误

return Task.FromResult(_inner.MoveNext())
错误:

System.AggregateException:发生一个或多个错误。
System.NullReferenceException:对象引用未设置为对象的实例

在lambda_方法(闭合、经验)
在System.Linq.EnumerableSorter
2.ComputeKeys(远程通讯[]元素,Int32
计数)
在System.Linq.EnumerableSorter中
1.Sort(远程通讯[]元素,Int32计数)
在System.Linq.OrderedEnumerable
1.d_u1.MoveNext()
在S360.Tests.TestDbAsyncEnumerator
1.MoveNextAsync(CancellationToken CancellationToken)


如果我删除
OrderBy
OrderBy x=>0
一切正常。任何解决方案如何模拟
DbContext
,使我的查询不会引发任何异常?

请参阅Microsoft文档中的
EF-in-memory-test-doubles的限制

当您在
Select()
中投影到
.DataSource
时,很可能该值为null,这会在您尝试访问
OrderBy()
中的
.Name
时导致NullReferenceException

当您对数据库执行此查询时,EF将看到对
数据源
导航属性的访问,并包括一个
连接
,以便获取它

在内存中执行时,不会发生此连接


您可以将预期的
数据源
实体添加到测试设置中的
报告
实体,或者更好地使用,它将填充导航属性,就像真实数据库一样。

在我的情况下,我还收到了与lambda_方法相关的异常:

System.NullReferenceException occurred
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=Anonymously Hosted DynamicMethods Assembly
  StackTrace:
       at lambda_method(Closure , InspectionAsset )
       at System.Linq.Enumerable.<>c__DisplayClass6_0`1.<CombinePredicates>b__0(TSource x)
       at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
       at AssetManagement.Model.Repositories.AssetDataService.<LoadOtherAssetsFromTrackAsset>d__18.MoveNext() in C:\src\AssetManagement\AssetManagement.Model\Repositories\AssetDataService.cs:line 135
  InnerException: 
为了消除异常,我将函数更改为:

    public async Task<IQueryable<Asset>> LoadAssetsOnTrack(IList<Asset> trackAssets, List<Asset> assets)
    {
        IQueryable<IAsset> query = assets.AsQueryable();

        foreach (var filter in Filters)
        {
            query = query.Where(filter);
        }
        await Task.Run(async () =>
        {
            using (await _assetsMutext.LockAsync())
            {
                var equipmentList = this.GetEquipment();

                foreach (var asset in trackAssets)
                {
                    if (!AssetRepository.GetIsAssetTrackType(asset.TypeCode))
                    {
                        var equipment = equipmentList.Where(x => x.AssetID== asset.AssetID).FirstOrDefault();

                        var inspectionAsset = new Asset()
                        {
                            AssetID = equipment?.AssetID,
                            Description = equipment?.Description,
                            // ...
                        };
                        // ...
                        assets.Add(inspectionAsset);
                    }
                }
            }
        });

        return query;
    }
公共异步任务LoadAssetContrack(IList trackAssets,列表资产)
{
IQueryable query=assets.AsQueryable();
foreach(过滤器中的var过滤器)
{
query=query.Where(过滤器);
}
等待任务。运行(异步()=>
{
使用(wait_assetsMutext.lockancy())
{
var equipmentList=this.GetEquipment();
foreach(trackAssets中的var资产)
{
如果(!AssetPository.GetIsAssetTrackType(asset.TypeCode))
{
var equipment=equipmentList.Where(x=>x.AssetID==asset.AssetID).FirstOrDefault();
var inspectionAsset=新资产()
{
AssetID=设备?AssetID,
描述=设备?描述,
// ...
};
// ...
资产。添加(检查资产);
}
}
}
});
返回查询;
}
也就是说,我仍然不完全清楚为什么我会偶尔在函数的顶部版本中得到异常,而在底部版本中没有得到异常。如果有人有任何进一步的见解,请让我知道

    public async Task<IQueryable<Asset>> LoadAssetsOnTrack(IList<Asset> trackAssets, List<Asset> assets)
    {
        IQueryable<IAsset> query = assets.AsQueryable();

        foreach (var filter in Filters)
        {
            query = query.Where(filter);
        }
        await Task.Run(async () =>
        {
            using (await _assetsMutext.LockAsync())
            {
                var equipmentList = this.GetEquipment();

                foreach (var asset in trackAssets)
                {
                    if (!AssetRepository.GetIsAssetTrackType(asset.TypeCode))
                    {
                        var equipment = equipmentList.Where(x => x.AssetID== asset.AssetID).FirstOrDefault();

                        var inspectionAsset = new Asset()
                        {
                            AssetID = equipment?.AssetID,
                            Description = equipment?.Description,
                            // ...
                        };
                        // ...
                        assets.Add(inspectionAsset);
                    }
                }
            }
        });

        return query;
    }