Как легко повторно использовать классы POCO, имеющие ссылку на сторонний класс POCO - .NET Core EF - PullRequest
0 голосов
/ 27 июня 2018

Этот пост довольно специфичен, но я постараюсь обобщить его как можно больше. Не обращаясь непосредственно ко всей справочной информации, главный вопрос: Каков наилучший способ или реализация для проекта API, встроенного в .NET Core 2 и EF Core, для простого повторного использования вашего собственного набора классов POCO, которые ссылаются на сторонние классы POCO, и с повторным использованием я имею в виду, что ваши собственные классы POCO не должны зависеть от сторонних сторон от их свойств класса POCO, но ваши конечные точки по-прежнему должны иметь возможность (легко) получать данные (значения / свойства) из сторонних классов POCO.

Легко написать конечные точки, которые получают поля и значения ваших собственных классов POCO и сторонних классов POCO, используя простой .Include и убедившись, что ссылочная таблица / класс POCO находится в вашем собственном классе POCO. , Это, однако, также означает, что когда третья сторона становится другой стороной, все конечные точки должны быть переписаны, поскольку новая третья сторона имеет свой собственный набор свойств / классов POCO. Функциональность нашего интерфейса / приложения, тем не менее, более или менее останется прежней, а у сторонних производителей их значения / свойства будут более или менее одинаковыми (хотя названия / настройки для определенных таблиц или столбцов могут отличаться).

Некоторая справочная информация

Я попытаюсь нарисовать текущую ситуацию, как она есть сейчас, для этого я буду использовать наш класс / таблицу Commodity POCO в качестве примера. Таким образом, наше API-решение, которое вызывается интерфейсным приложением, имеет 2 проекта: проект DAL, в котором размещена вся логика данных / базы данных (Fluent API), и сам проект API, в котором находятся конечные точки, модели представления, логика управления пользователями и т. Д. Я максимально упростил это:

enter image description here

Все классы таблиц / POCO нашей собственной базы данных находятся в папке OwnModels, а модели сторонних производителей создаются в папке TheirModels. Их классы POCO воссоздаются с документом спецификации (файл swagger), который они отправили нам. В нашей базе данных есть несколько таблиц, которые сделаны самим собой, и другой набор таблиц, которые действуют как reference table между нашей таблицей базы данных и их таблицей, Commodity - одна из них. У нас запущен процесс, который синхронизирует данные своей базы данных / таблиц с нашей собственной базой данных (в воссозданных таблицах).

В этом примере у них есть таблица с именем TheirCommodity с 3 полями TheirCommodityID, Name и SortOrder. Теперь мы создали таблицу ссылок (класс POCO) с тем же именем, но без префикса, поэтому Commodity. В этой таблице есть столбец для собственного идентификатора (CommodityID) и ссылочного идентификатора их таблицы (ItsCommodityID), в Fluent это устанавливается как отношение один к одному. Большинство конечных точек справочных таблиц доступны только для чтения (GET конечная точка) просто потому, что нам не разрешено изменять / удалять / вставлять данные непосредственно в их таблицы.

Указанные выше товарные таблицы теперь настроены следующим образом:

Их товарный класс POCO:

public class TheirCommodity
{
    public TheirCommodity()
    {   
    }

    public long TheirCommodityID { get; set; }

    public string Name { get; set; }

    public long? SortOrder { get; set; }

    [JsonIgnore]
    public virtual Commodity Commodity { get; set; }
}

Наш (справочный) товарный класс POCO:

public class Commodity
{
    public Commodity()
    {
    }

    public long CommodityID { get; set; }

    public long TheirCommodityID { get; set; }

    public virtual TheirCommodity TheirCommodity { get; set; }
}

Атрибут [JsonIgnore] добавлен, потому что, если нет, он попадает в циклическую ссылку при извлечении данных для нашей таблицы Commodity (оба класса POCO ссылаются на каждую выдру для получения правильного отношения один к одному в FLUENT ).

В API я создал конечную точку GET для этого товара следующим образом:

[HttpGet]
public async Task<IEnumerable<Commodity>> GetCommodities()
{
    return await this.Context.Commodity
        .Include(i => i.TheirCommodity)
        .ToListAsync();
}

Вопрос

Все вышеперечисленное прекрасно работает, но это огромная проблема, когда повторно используйте этот код для другой компании, у которой есть другая третья сторона со своим набором таблиц и свойств. Эта установка будет означать, что нам придется переписать все наши конечные точки и некоторые другие.Поэтому в идеале, по крайней мере, я думаю (но это также вопрос), вы бы хотели получить все свойства их класса POCO в нашем собственном классе POCO, чтобы мы не зависели (с включением) от их классов POCO. Но это также означает, что вам нужна логика: когда вы получаете значения из их таблиц / свойств, вам нужно написать вспомогательное поле или что-то, что запрашивает таблицу третьей стороны.
Я не могу полностью обернуть голову, как это должно быть достигнуто. Я знаю, что вы не можете написать идеальный кусок кода, который можно использовать повторно (также, поскольку у нас всегда будет шаг к получению сторонних таблиц в вашей собственной базе данных для синхронизации данных), но, по крайней мере, должно быть что-то не нужно переписывать все наши конечные точки. Мои извинения за большую текстовую стену, но я не мог найти способ написать это короче. А также мои извинения за неправильное использование слов (английский не мой родной язык :))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...