Я работаю в среде, где вся новая работа выполняется в AspNetCore, и одна из основных причин заключается в том, что мы можем запускать ее на серверах Linux. У нас есть API для доступа к одной из наших баз данных, к которой меня попросили добавить OData. Без проблем.
Эта проблема
У меня есть прекрасный пример, работающий в тестовом проекте, и я переношу его на реальный API в ветке кода, ааааааааа.....что это? Это отсылка к Microsoft.AspNet
.
Мой тестовый проект — .NetCore 2.1, и установлены только следующие пакеты NuGet:
Этот (усеченный) код отлично работает на моем компьютере для разработки Windows, но я предвижу проблемы, когда мы попытаемся собрать его для развертывания Linux.
Startup.cs — Обратите внимание на первые 2 использования
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OData.Edm;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ODataTest.Models;
namespace ODataTest
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddOData();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseMvc(b =>
{
b.Filter().Expand();
b.MapODataServiceRoute("odata", "odata", GetEdmModel());
b.EnableDependencyInjection();
});
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<ThingDto>(nameof(ThingDto));
return builder.GetEdmModel();
}
}
}
ThingController.cs — уведомление с использованием № 3
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
using ODataTest.Models;
namespace ODataTest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ODataController
{
private readonly Db _db;
public ValuesController(Db db)
{
this._db = db;
}
[HttpGet]
[EnableQuery]
public ActionResult<IEnumerable<ProductPricePointMarkdownDto>> Index()
{
var things =
from thing in _db.Things
select new ThingDto
{
ThingID = thing.ID,
StyleID = thing.StyleID,
ColourID = thing.ColourID
};
return Ok(things);
}
}
}
ThingDto.cs — обратите внимание на последнее использование
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.OData.Query;
namespace ODataTest.Models
{
[Filter("ColourID", Disabled = true)]
[Filter]
public class ThingDto
{
[Key]
public int ThingID { get; set; }
public int StyleID { get; set; }
public int ColourID { get; set; }
}
}
Может ли кто-нибудь отвлечь меня от моего нынешнего мнения о том, что OData «работает с Core» — это маркетинг, а на самом деле это не так?
Итак, ответ: «Да, это работает». Я не выяснил, является ли это плохим пространством имен или действительно относится к .NET Standard. Мотивация выяснить это исчезла, как только я доказал, что это работает в док-контейнере Linux.
Небольшой комментарий: верните IQueryable<T> вместо IEnumerable<T>, чтобы вы могли выполнять запросы на стороне сервера, а не только в памяти. Возвращая свои DTO как IEnumerable<T>, вы теряете эту возможность.