Я использую Microsoft docs для насмешки 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
, он выдает ошибку в TestDbAsyncEnumerator.MoveNextAsync
в этой строке
return Task.FromResult(_inner.MoveNext())
Ошибка:
System.AggregateException: произошла одна или несколько ошибок.
System.NullReferenceException: ссылка на объект не установлена в экземпляр объекта.на lambda_method (Закрытие, Опыт)
в System.Linq.EnumerableSorter2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter2.ComputeKeys(TElement[] elements, Int32 count)
1.Sort (элементы TElement [], количество Int32)
at System.Linq.EnumerableSorter
в System.Linq.OrderedEnumerable1.<GetEnumerator>d__1.MoveNext()
at S360.Tests.TestDbAsyncEnumerator1.<GetEnumerator>d__1.MoveNext()
at S360.Tests.TestDbAsyncEnumerator1.<GetEnumerator>d__1.MoveNext()
1.MoveNextAsync(CancellationToken cancelationToken)
at S360.Tests.TestDbAsyncEnumerator
Если я удалю OrderBy
или OrderBy x => 0
все будет хорошо. Любые решения, как я могу издеваться над DbContext
чтобы мой запрос не DbContext
никаких исключений?
В моем случае я также получил исключение, связанное с lambda_method:
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:
Для меня я изначально query = query.Where(filter);
данные, подобные этому, с исключением, происходящим в query = query.Where(filter);
:
using Nito.AsyncEx;
// ...
private static readonly AsyncLock _assetsMutext = new AsyncLock();
public List<Expression<Func<sset, bool>>> Filters { get; } = new List<Expression<Func<Asset, bool>>>();
// ...
public async Task<IQueryable<Asset>> LoadAssetsOnTrack(IList<Asset> trackAssets, List<Asset> assets)
{
IQueryable<IAsset> query = null;
await Task.Run(async () =>
{
using (await _assetsMutext.LockAsync())
{
var equipmentList = this.GetEquipment();
Parallel.ForEach(trackAssets, (asset, state) =>
{
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);
}
});
query = assets.AsQueryable();
foreach (var filter in Filters)
{
query = query.Where(filter);
}
}
});
return query;
}
Чтобы исключить исключение, я изменил функцию следующим образом:
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;
}
Тем не менее, мне все еще не совсем ясно, почему я спорадически получаю исключение в верхней версии функции и не получаю ее в нижней версии. Если у кого-то есть какие-либо дальнейшие мысли, пожалуйста, дайте мне знать.
См. Limitations of EF in-memory test doubles
в документации Microsoft.
Когда вы проецируете на .DataSource
в Select()
, это, скорее всего, это null, что вызывает исключение NullReferenceException при попытке доступа .Name
в OrderBy()
.
Когда вы выполняете этот запрос для базы данных, EF увидит доступ к свойству навигации DataSource
и включит JOIN
чтобы он был извлечен.
При выполнении в памяти это соединение не происходит.
Вы можете добавить ожидаемый объект DataSource
объекту " Reports
в вашей тестовой настройке или, еще лучше, использовать провайдер данных " Усилия", который будет заполнять свойства навигации, как и реальная база данных.