возвращаемая сущность, сформированная из двух разных баз данных в пределах одной конечной точки веб-API odata - PullRequest
0 голосов
/ 23 октября 2018

У меня есть 2 базы данных, необходимые для поддержки одного веб-API.Я хочу вернуть новый "объект", который отражает объекты из обеих баз данных.Я называю эту сущность «представлением», даже если оно не имеет отношения к представлению в базе данных, а данные поступают из двух разных баз данных.Данные будут использоваться для питания страницы пользовательского интерфейса.

Для другой аналогичной проблемы, которая требовала возврата новой формы данных из одной базы данных, я настроил новый объект NotMapped, вызывающий PeopleHomeView, и добавил один Find функционирует на контроллере, так что когда я получаю доступ к /PeopleHomeViews/NS.Find(id='...'), я возвращаю объект, который имеет пользовательскую форму.Сущность имеет только примитивные значения данных, без типов ссылок.Все это работало нормально.

Однако мне нужно вернуть объект, который объединяет данные из 2 баз данных, что представляет собой другую проблему.

  • Настройка 2 DbContexts, по одному для каждой базы данных,Оба вводятся в контроллер.
  • Определен класс .net со свойствами, которые я хотел получить в возвращаемых данных.Свойства имели объекты, которые отражают две разные модели сущностей базы данных.Так что в PersonEntityView у меня есть Person объект и Rating объект.Person и Rating происходят из разных баз данных.
  • Создан элемент управления PersonEntityViewsController и добавлен builder.EntitySet<PersonEntityView>("PersonEntityViews") в конструктор моделей EDM.У меня нет другого кода компоновщика EDM.
  • Добавлен метод Get([FromODataUri] Guid key) для контроллера PersonEntityViewsController.Ключ, переданный в Get, является ключом Person.Затем я использую linq для ручной сборки данных, которые мне нужно вернуть.

    public PersonEntityView Get(
           [FromODataUri] Guid key)
    {
        ...controller code to build up PersonEntityView...
        var x = new PersonEntityView();
        ...
        return x;
    }
    

Теперь, когда я получаю доступ к /PeopleEntityViews(..guid of person...), создаю возвращаемую сущность и возвращаю ее из Get, яполучать только примитивные значения данных в классе .net, и хотя я вручную создаю содержимое сущности, например, добавляю Person и Rating.Они не сериализуются обратно клиенту.Метаданные $ показывают свойства навигации правильно.Использование расширений, например $expand=Person, не работает.

Я видел некоторые другие сообщения SO по этому вопросу, но они не относились к проблеме.Например, возврат DTO описан в документации, но не из двух разных баз данных.

Я не хочу, чтобы мой клиент несколько раз просил загрузить наборы справочных данных и других данных, необходимых для страницы,Я хотел бы получить большую часть этого в одном запросе, но все еще использовать бэкэнд odata.

Мысли о том, как это сделать?Кажется, что данные могут быть чувствительны к типу возврата из контроллеров, поэтому, возможно, мне нужно что-то особенное в моем типе возврата или я пропускаю аннотацию.

1 Ответ

0 голосов
/ 25 октября 2018

Похоже, что для корректной активации форматировщиков оддаты требуется довольно строгий набор возвращаемых типов.Не совсем уверен в правилах, поэтому мне придется читать исходный код odata более внимательно.Чтобы заставить это работать, мне пришлось вернуть IQueryable из Get, поэтому я сделал:

public IQueryable<PersonEntityView> Get([FromOdataUri] Guid key) {
  ...
  (new List<PersonEntityView>{v}.AsQueryable();
}

Сигнатура не имеет для меня большого смысла, так как Get для получения на основе ключа должен просто возвращать одинсущность и, следовательно, не нужно иметь IQueryable.Возвращаемое значение является членом массива в свойстве value.Если вы используете только IQueryable без типа, он возвращает объект json, но ему не хватает полного формата ответа odata.Мне все еще нужно было расширить свойство с помощью ?$expand=ThePropertyToExpand, иначе расширение не состоялось бы.

Я буду продолжать играть с ним, но это, кажется, лучший способ вернуть не базу данных, подкрепленную (следовательно, не отображенную вentityframework) объекты, которые сильно настроены для нужд конкретного представления пользовательского интерфейса и не основаны только на одном корне объекта.

Вы также можете исключить это из функций / действий, скажем, используя связанную сущность, которую я описываю здесь .Однако в некоторых случаях значение может не быть аккуратно связано с одним корневым объектом.

...