0

我想我很简单地错过了一些东西,但这就是我想要做的。我有一个带有 EF Core 5 + OData 7.5.6 的 .NET Core 5 项目。除了在生成的 SQL 查询中插入 TOP 命令外,一切似乎都在工作。这是我的控制器。很简单。

[EnableQuery]
[ApiController]
[Route("odata/[controller]")]
public class ConferenceHistoryController : ControllerBase
{
    private readonly cdr_database_2Context _db;

    public ConferenceHistoryController(cdr_database_2Context db)
    {
        _db = db;
    }

    [HttpGet]
    public IEnumerable<_000701CallDataRecord> GetConferenceList()
    {
        // Return Full List
        var query = _db._000701CallDataRecords;
        var qs = query.ToQueryString();
        return query.ToList();
    }
}

当我将请求发送至:

https://localhost:44355/odata/ConferenceHistory/?$select=RecordId,version&$top=5

生成的 SQL 查询是:

SELECT [0].[endDateTime], [0].[id], [0].[organizer], [0].[ParticipantCount], [0].[participants], [0].[PoorCall], [0].[type], [0].[version]

从 [000701_CallDataRecord] 作为 [0]

如您所见,它缺少 TOP 和 SELECT 命令。我的 Startup.cs 中有以下内容

public void ConfigureServices(IServiceCollection services)
    {
        // Add CORS to Project
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
        });

        // Add OData
        services.AddOData();
        services.AddControllers();
        services.AddDbContext<cdr_database_2Context>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("CDRConnection"))
            );

        // Add Swagger Support
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "ODataAPI", Version = "v1" });
        });
        SetOutputFormatters(services);
    }

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Use HTTPS & Routing
        app.UseHttpsRedirection();
        app.UseRouting();

        // Auth???
        app.UseAuthorization();

        // Swagger Configure
        app.UseSwagger();
        app.UseSwaggerUI((config) =>
        {
            config.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Odata Demo Api");
        });

        // Setup Endpoint for EDM
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.EnableDependencyInjection();
            endpoints.Select().Expand().Filter().OrderBy().MaxTop(50).Count();
            endpoints.MapODataRoute("odata", "odata", GetEdmModel());
        });
    }

private IEdmModel GetEdmModel()
    {
        // Add OData - EDM Definitions Below
        var odataBuilder = new ODataConventionModelBuilder();
        odataBuilder.EntitySet<WeatherForecast>("WeatherForecast");
        odataBuilder.EntitySet<_000701CallDataRecord>("ConferenceHistory");

        return odataBuilder.GetEdmModel();
    }

只是在寻找我可能出错的方向。其他一切似乎都运行良好。

4

2 回答 2

0
  1. 您的控制器需要从 ODataController 而不是 ControllerBase 派生
  2. 你需要用 [Queryable] 装饰 GetConferenceList()
于 2021-03-19T04:15:23.277 回答
0

好的,我发现问题出在我的上面。这是使用 .ToList 和 IEumerable。所以如果我改变了这个:

[HttpGet]
public IEnumerable<_000701CallDataRecord> GetConferenceList()
{
    // Return Full List
    var query = _db._000701CallDataRecords;
    var qs = query.ToQueryString();
    return query.ToList();
}

至:

[HttpGet]
public IEnumerable<_000701CallDataRecord> GetConferenceList()
{
    // Return Full List
    var query = _db._000701CallDataRecords;
    var qs = query.ToQueryString();
    return query;
}

有用。还值得注意的是 .ToQueryString() 不显示 TOP 命令的 OData/EF 插入。但是如果我在 Startup.cs 文件中启用 .EnableSensitiveDataLogging() ,那么我清楚地看到它被插入其中。

显然,调用 .ToList() 将导致它处理并忽略任何花哨的 OData 命令。那是唯一的变化,那时一切都很好。

于 2021-03-19T15:25:36.250 回答