Изменение модели Entity Framework во время выполнения - PullRequest
14 голосов
/ 26 октября 2010

Это чисто концептуальная и дизайнерская идея, связанная с EF4.

Пример / сценарий представляет собой большую систему типа ERP или CRM, где компаниям может потребоваться добавить традиционные «пользовательские поля» для сбора дополнительных данных.

Я знаю, что EF имеет некоторые возможности для выталкивания модели в базу данных во время выполнения, но на самом деле вопрос в том, можете ли вы использовать EF для изменения модели и обновления хранилища данных в режиме реального времени?

Другими словами, если я предоставлю пользователю механизм для добавления определенного пользователем столбца, связанный тип данных и нулевые требования, это можно сделать на лету с EF и затем запомнить для всех будущих сеансов?

Это там, но я думаю, вы все увидите, к чему я клоню.

Brent

Ответы [ 5 ]

14 голосов
/ 26 октября 2010

Мне задавали этот вопрос несколько раз в прошлом. Там нет очевидного или простого способа. Возможно, что нет пути, но мы разработчики, и всегда есть способ! Знаю ли я, что это такое? Могу ли я придумать несколько идей? .... Мммм ... во время выполнения модель основана на строго типизированных классах из пространства метаданных. Вы можете создавать их на лету. Но тогда вам нужно изменить xml файла edmx. Для этого есть LINQ to XML или xpath. Изменение схемы базы данных ... как модель сначала строит dbs ... она создает sql, а затем вы ее выполняете. Вам нужно будет создать sql (как? Shrug) и выполнить его (objectcontext.executestorecommand ()). Реализуемое? Возможный? Я понятия не имею. На самом деле ответ - нет ... в VS или .NET 4 (EF APIs) нет ничего, что могло бы легко включить это, насколько я знаю. Конечно, кто-то более умный и терпеливый, чем я, потратил (впустую?) Много времени (пытаясь) перехитрить EF, чтобы осуществить это. Однако, основываясь на вашем ответе на предложение в блоге Джереми, вы ищете что-то встроенное / удобное. На это проще ответить «Нету».

Julie

11 голосов
/ 29 октября 2010

Часто существует несколько способов решения проблемы, и это не исключение. В этом случае вам нужно разрешить пользователям добавлять новые поля в ваше приложение и базу данных и использовать эти поля из вашего приложения. Вот несколько способов сделать это:

a) Разрешить пользователям изменять схему базы данных.
б) Создайте отдельную структуру для определения «пользовательских полей» и хранения в них данных.
c) Создайте пустые «зарезервированные» поля в таблицах, где пользователям, скорее всего, понадобятся свои собственные поля.

Я предпочитаю подход (b), а иногда - (c) всякий раз, когда в приложении требуются пользовательские настраиваемые поля. Вот некоторые плюсы / минусы для каждого из трех:

Изменить схему

Рискованно : Если вы позволите пользователям изменять схему базы данных, где вы проведете линию? Если они могут добавлять поля, они также могут изменить определение существующих полей, добавить или удалить индексы и т. Д. Это может привести к кошмару поддержки с ошибками, проблемами производительности и т. Д., Вызванными изменениями схемы, выполненными пользователями.
Performant : хранение новых пользовательских полей, встроенных в существующие таблицы, обычно дает преимущество в производительности по сравнению с отдельной структурой, но только до тех пор, пока они не выходят за рамки изменений.
Clunky : EF определяет схему во время разработки, поэтому для выполнения этой работы во время выполнения вам потребуется генерировать новые классы сущностей во время выполнения с членами, представляющими новые поля, и вам нужно будет обновить отображение метаданные во время выполнения. Сгенерированные во время выполнения классы сущностей могут наследоваться от сгенерированных классов во время разработки, поэтому вам нужно только добавить членов и сопоставления для новых пользовательских полей. Хотя возможно, это неуклюже. Код, который использует классы, созданные во время выполнения, должен использовать отражение для доступа к новым членам, созданным во время выполнения.

Отдельная структура

Удобный для пользователя: Создав отдельную структуру для хранения пользовательских полей, вы можете создать логику приложения для пользователей, чтобы добавлять / удалять эти поля и т. Д. Им не нужно связываться с базой данных, вместо этого вы можете иметь формы обслуживания в приложении для добавления новых полей.
EF-friendly: нет необходимости связываться с классами сущностей и отображать метаданные во время выполнения. Все определяется во время разработки, а пользовательские поля - это просто данные.
Чуть менее производительный: Наличие отдельных таблиц для определения и хранения пользовательских полей может сделать поиск немного более дорогостоящим из-за дополнительных циклических переходов или дополнительных объединений.

Separate table structure for user defined fields

Зарезервированные поля

Достаточно часто: Во многих ситуациях пользовательские поля используются только для одного или нескольких дополнительных полей. Резервирование пары столбцов часто покрывает 99% потребностей пользователей. Даже общее поле «примечания» в каждой таблице часто достаточно в приложениях больших объектов.
Limited: Если пользователи хотят больше полей, чем вы зарезервировали, или других типов данных, которые вы зарезервировали, это может быть ограничением.
Исполнитель: Встроенные столбцы, извлеченные без дополнительных возвратов или объединений.
Определено во время разработки: Нет времени выполнения возни с определениями или отображениями типов сущностей.

Reserved fields

2 голосов
/ 19 сентября 2012

Брент пинговал меня сегодня в Твиттере (почти через 2 года после этого поста), чтобы посмотреть, изменилось ли что-нибудь.Этот сценарий до сих пор не поддерживается EF.Однако у Роуэн Миллер есть интересная статья о том, как это сделать с помощью Code First http://romiller.com/2012/03/26/dynamically-building-a-model-with-code-first/

. Это может или не может сделать то, что вам нужно, но стоит посмотреть.

1 голос
/ 26 октября 2010

Джереми Миллер обсуждает подобную установку в этой статье .Он использует nHibernate, но он может дать вам некоторые идеи.

0 голосов
/ 21 июня 2016

Это версия ответа Reserved fields от @KristoferA, который я использовал в прошлом.

Вы можете добавить один дополнительный столбец XML (или JSON) в каждую таблицу, которая, вероятно, потребует пользовательских данных, а затем читать / записывать их из БД, используя EF. После прочтения десериализуйте XML (JSON) и передайте его механизму, который должен обрабатывать сопоставления, затем представьте его пользователю. То же самое касается записи данных, которые вы читаете из UI -> map to object -> serialize в XML (JSON) -> и записи в эти дополнительные поля.

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