Недавно я реализовал OData в своем веб-API ASP .NET Core.Я добился успеха, пока возвращаю модели баз данных напрямую.Однако у меня возникают проблемы, как только я пытаюсь вернуть модели предметной области.
Основная проблема заключается в сопоставлении класса данных с классом домена при сохранении типа возвращаемого значения IQueryable.Хотя я нашел частичный успех при использовании метода расширения MapTo в AutoMapper, я обнаружил, что мне не удается использовать метод $ extended для расширения коллекции объектов, которые также являются объектами домена.
Я создал пример проекта для иллюстрацииЭта проблема.Вы можете просмотреть или скачать полный проект на github здесь .Смотрите описание ниже.
С учетом следующих двух классов баз данных:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<Order> Orders { get; set; }
public Product() {
Orders = new Collection<Order>();
}
}
public class Order
{
public int Id { get; set; }
public Double Price { get; set; }
public DateTime OrderDate { get; set; }
[Required]
public int ProductId { get; set; }
public Product Product { get; set; }
}
и следующих моделей доменов ...
public class ProductEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<OrderEntity> Orders { get; set; }
}
public class OrderEntity
{
public int Id { get; set; }
public Double Price { get; set; }
public DateTime OrderDate { get; set; }
[Required]
public int ProductId { get; set; }
public Product Product { get; set; }
}
И контроллера продуктов
public class ProductsController
{
private readonly SalesContext context;
public ProductsController(SalesContext context) {
this.context = context;
}
[EnableQuery]
public IQueryable<ProductEntity> Get() {
return context.Products
.ProjectTo<ProductEntity>()
.AsQueryable();
}
}
Все следующие запросы OData проходят:
Следующееоднако запрос не проходит:
HTTP-ответ никогда не возвращается.Единственное сообщение об ошибке, которое я получаю, приходит с консоли:
System.InvalidOperationException: Sequence contains no matching element at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
Наконец, вот ссылка на профиль сопоставления:
public static class MappingProfile
{
public static void RegisterMappings() {
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Order, OrderEntity>();
cfg.CreateMap<Product, ProductEntity>();
});
}
}
Я могу решить проблему, просто возвратив Listвместо IEnumerable в контроллере, но это, конечно, вызовет большой запрос к базе данных, который будет требовать высокой производительности.
Как указано выше, вы можете найти ссылку на полный проект на Github здесь .Дайте мне знать, если найдете ответы!