Отношение сущности запроса, которое является нулевым в ложном контексте Db

2

Я использую 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.EnumerableSorter 2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter
2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter
2.ComputeKeys(TElement[] elements, Int32 count)
at System.Linq.EnumerableSorter
1.Sort (элементы TElement [], количество Int32)
в System.Linq.OrderedEnumerable 1.<GetEnumerator>d__1.MoveNext()
at S360.Tests.TestDbAsyncEnumerator
1.<GetEnumerator>d__1.MoveNext()
at S360.Tests.TestDbAsyncEnumerator
1.<GetEnumerator>d__1.MoveNext()
at S360.Tests.TestDbAsyncEnumerator
1.MoveNextAsync(CancellationToken cancelationToken)

Если я удалю OrderBy или OrderBy x => 0 все будет хорошо. Любые решения, как я могу издеваться над DbContext чтобы мой запрос не DbContext никаких исключений?

Теги:
unit-testing
entity-framework
mocking
moq

2 ответа

0

В моем случае я также получил исключение, связанное с 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;
    }

Тем не менее, мне все еще не совсем ясно, почему я спорадически получаю исключение в верхней версии функции и не получаю ее в нижней версии. Если у кого-то есть какие-либо дальнейшие мысли, пожалуйста, дайте мне знать.

0

См. Limitations of EF in-memory test doubles в документации Microsoft.

Когда вы проецируете на .DataSource в Select(), это, скорее всего, это null, что вызывает исключение NullReferenceException при попытке доступа .Name в OrderBy().

Когда вы выполняете этот запрос для базы данных, EF увидит доступ к свойству навигации DataSource и включит JOIN чтобы он был извлечен.

При выполнении в памяти это соединение не происходит.

Вы можете добавить ожидаемый объект DataSource объекту " Reports в вашей тестовой настройке или, еще лучше, использовать провайдер данных " Усилия", который будет заполнять свойства навигации, как и реальная база данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню