Вчера я задал этот вопрос относительно наилучшей практики для простой системы поиска информации, над которой я начинаю работать.
Сегодня мой клиент спросил меня, можно ли разрешить ему добавлять поля в основной объект позднее, используя интерфейс администрирования. То есть приложение позволяет выполнять поиск по одной таблице базы данных (назовем ее «сущности»), которая может иметь различные ассоциации с другими объектами, но основное внимание уделяется сущностям.
Теперь, конечно, небо это предел, и это возможно.
Моя первоначальная мысль об этой проблеме - создать две новые таблицы:
Дополнительные поля (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;
Итак, мой вопрос: это разумно? Есть ли лучшее решение, которое я пропустил? Есть ли какие-либо последствия этого подхода, о которых я должен знать?
(Пожалуйста, прости мои глупые идентификаторы, это рано для меня:)