Лучший способ моделирования владения ресурсами

#sql-server #database #entity-framework

#sql-server #База данных #entity-framework

Вопрос:

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

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

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

Итак, какой способ был бы предпочтительным? Возникнет ли проблема с производительностью при хранении владения в одной таблице, учитывая, что в конечном итоге в ней может быть сотни тысяч записей (возможно, даже миллионы)? Как насчет стоимости сохранения множества ограничений внешнего ключа? Есть ли лучший способ решить эту проблему?

Спасибо

Ответ №1:

Вы работаете на объектно-ориентированном языке. Наследование идеально подходит для решения этой проблемы.

В зависимости от того, используете ли вы Code First или DB First, ваш подход будет немного отличаться, но сводится к следующему:

  1. Создайте и абстрактный класс, вы можете назвать его чем-то вроде «OwnableEntity». По сути, вы помещаете туда свой внешний ключ и свойство навигации.
  2. Наследование всех ваших объектов из этого «OwnableEntity»
  3. Убедитесь, что ваше сопоставление наследования в EF правильное (в этом случае вы, вероятно, захотите использовать сопоставление наследования TPC)

С этого момента вы можете написать свою логику «проверки владения» для «OwnableEntity», и это будет нормально для каждой сущности, которую вы реализуете позже.

Комментарии:

1. Звучит неплохо. Если я правильно понимаю TPC, это приведет к тому, что (при условии, что класс владения является абстрактным) каждая таблица конкретного типа будет содержать два столбца, которые будут одинаковыми во всех других конкретных классах. Одна ссылка на владельца и один столбец OwnableEntity-key . Таким образом, сведения о владельце не будут храниться в отдельной таблице, а будут распределены по каждой конкретной таблице подтипов. Каким-то образом принудительно, чтобы две записи конкретного типа в разных таблицах не использовали один и тот же OwnableEntity-key?