EFCore Cosmos db Expand Operation Throws - не удалось перевести выражение LINQ 'o0' - PullRequest
0 голосов
/ 21 апреля 2020

Ниже приведена схема моей модели:

{
  "id": "5dd673d9-2104-4ebe-a56b-5b92ef36739b",
  "InvName": "Demo Inv Name",
  "ObsCollection": [
  {
     "ObsId": "52d673d9-2104-4ebe-a56b-5b92ef36739b",
     "InvId": "5dd673d9-2104-4ebe-a56b-5b92ef36739b",
     "ObsName": "Demo!"
  }
  ],
  "CV": {
      "CodeId": 401,
      "Value": "Demo Value for CV"
  },
  "Owner": {
      "UserId": "abc",
      "Name": "ABC DEF"
  }
}

Ниже приведено мое сопоставление сущностей:

    public override void Configure(EntityTypeBuilder<Inv> builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        #region Container
        builder.ToContainer("Inv");
        #endregion

        #region PartitionKey
        builder.HasPartitionKey(o => o.Id);
        #endregion

        #region PropertyNames
        builder.Property(prop => prop.Id).ToJsonProperty("id");
        #endregion

        builder.HasNoDiscriminator();

        builder.HasKey(p => p.Id);

        builder.OwnsOne(property => property.Owner);

        builder.OwnsOne(property => property.CV);

        builder.OwnsMany(p => p.ObsCollection, a=> {

            a.WithOwner().HasForeignKey("OwnerId");

            a.HasKey("ObsId");
        });

    }

Метод моего контроллера для GET:

    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<Inv>), 200)]
    public IActionResult Get(ODataQueryOptions<Inv> opts)
    {

        var investigations =
            _investigationService
                .GetAllInvestigationsAsync(opts);

        return Ok(investigations);
    }

И мой метод _investigationService.GetAllInvestigationsAsyn c содержит:

    public IQueryable GetAllInvestigationsAsync(ODataQueryOptions<Inv> options)
    {
        try
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // This is a workaround for a limitation in EFCore. EFCore translates
            // PageSize to .Top<T>() LINQ query. Adding $top to the query introduces
            // another .Top<T>() LINQ query. When this LINQ (.Top<T>().Top<T>())
            // get translated, the resulting SQL statement becomes invalid.
            ODataQuerySettings settings = new ODataQuerySettings()
            {
                PageSize = options.Top == null ? 100 : options.Top.Value
            };

            // We are ignoring the Top, because the Page Size already account for 
            // the top.
            AllowedQueryOptions ignoredQueryOptions = AllowedQueryOptions.Top;

            var results =
                options.ApplyTo(
                    _repository
                        .GetAllAsync(),
                    settings,
                    ignoredQueryOptions);

            return 
                results;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Investigation Service Error - GetInvestigationsAsync: {Message}", ex.Message);
            throw;
        }
    }

И, наконец, мой репозиторий:

    public IQueryable<TEntity> GetAllAsync()
    {
        try
        {

            var data =
                _context.Set<TEntity>()
                    .AsQueryable();

            return Entities.AsQueryable<TEntity>();
        }
        catch (Exception)
        {
            throw;
        }
    }

Когда я пытаюсь выполнить операцию GET на URL:

https://localhost: 5003 / odata / Invs ? $ Expand = ObsCollection

Ниже приведена ошибка, которую я получаю:

Выражение LINQ 'o0' не может быть в переводе. Либо переписайте запрос в форме, которую можно перевести, либо переключитесь на оценку клиента явно, вставив вызов либо в AsEnumerable (), AsAsyncEnumerable (), ToList (), либо в ToListAsyn c (). См. https://go.microsoft.com/fwlink/?linkid=2101038 для получения дополнительной информации.

До сих пор у меня работали Select, Filter, Skip и Top. Мне нужна помощь с расширением работы.

...