Как справиться с программным добавлением полей? - PullRequest
0 голосов
/ 22 мая 2009

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

Сегодня мой клиент спросил меня, можно ли разрешить ему добавлять поля в основной объект позднее, используя интерфейс администрирования. То есть приложение позволяет выполнять поиск по одной таблице базы данных (назовем ее «сущности»), которая может иметь различные ассоциации с другими объектами, но основное внимание уделяется сущностям.

Теперь, конечно, небо это предел, и это возможно.

Моя первоначальная мысль об этой проблеме - создать две новые таблицы:

Дополнительные поля (FieldID PK , FieldName, IsShownInSearchResults и другие метаданные) Это таблица, в которой строки будут созданы интерфейсом администратора. Например, если клиент позже решит, что он хочет добавить возможность отслеживать, скажем, цвет глаз сущности, он создаст дополнительное поле с именем поля «Цвет глаз».

AdditionalFieldData (FieldDataID PK , EntityID FK , FieldID FK , FieldValue) Это таблица, связывающая сущности с их соответствующие значения для любых дополнительных полей, добавленных клиентом. Например, в нашем примере цвета глаз, если у нас есть два Entity (EntityID 3 и 4) во время добавления поля, а новый AdditionalField имеет FieldID, равный 1, допустимо не иметь данных цвета глаза, связанных с объектами. , Затем клиент может выбрать, чтобы добавить цвет глаз «Синий» в Entity 3, и мы добавили бы строку к AdditionalFieldData, например: ( автоматически сгенерированный PK , 3, 1, «Синий»).

Поскольку я хочу легко выполнять поиск по ним, мне просто потребуется, чтобы все дополнительные поля имели строковые значения.

Следуя подходу, который я опубликовал в предыдущем вопросе, я буду использовать Linq-To-SQL с запросом, подобным следующему, для поиска информации, когда пользователь выполняет поиск (конечно, логика фильтрации будет более сложный на практике):

var results = from s in db.Stuff
          where (s.Name.Contains(textFilter) ||
                 s.Title.Contains(textFilter))
          select s;

Я бы изменил запрос так, чтобы он выглядел примерно так:

var results = from s in db.Stuff
              where (...existing filter logic...) ||
                    s.AdditionalFieldData.Any(afd => afd.FieldName.Contains(textFilter))
              select s;

Итак, мой вопрос: это разумно? Есть ли лучшее решение, которое я пропустил? Есть ли какие-либо последствия этого подхода, о которых я должен знать?

(Пожалуйста, прости мои глупые идентификаторы, это рано для меня:)

1 Ответ

1 голос
/ 22 мая 2009

Я не эксперт по LINQ, но с точки зрения дизайна базы данных то, что вы предлагаете, мне кажется вполне подходящим.

Альтернатива, которую я видел несколько раз, состоит в том, чтобы в таблице сущностей был задан целый набор «запасных» полей, которые пользователи могут включать / отключать через интерфейс администратора. Таким образом, вы получаете некоторую производительность базы данных (из-за меньшего числа объединений), но вам нужно заранее выбрать, сколько из этих запасных полей вы хотите, и в большинстве случаев вы получите большие, в основном пустые таблицы.

О, и вы можете смело предположить, что если вы решите добавить N запасные поля, ваши пользователи захотят N + 1 ; -)

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