2010-10-26 7 views
14

Il s'agit purement d'une idée conceptuelle et conceptuelle liée à EF4. L'exemple/scénario est un grand système de type ERP ou CRM dans lequel les entreprises peuvent avoir besoin d'ajouter des «champs définis par l'utilisateur» traditionnels pour capturer des données supplémentaires.Modification d'un modèle de cadre d'entité au moment de l'exécution

Je sais que l'EF a quelques fonctionnalités pour faire sortir le modèle d'une base de données à l'exécution, mais la vraie question est: pouvez-vous utiliser EF pour modifier un modèle et mettre à jour le magasin de données en temps réel? En d'autres termes, si je fournis à l'utilisateur un mécanisme pour ajouter une colonne définie par l'utilisateur, le type de données associé et les exigences nulles peuvent-elles être effectuées à la volée avec EF et mémorisées pour toutes les futures sessions?

C'est là-bas mais je pense que vous verrez tous ce que je veux dire.

Brent

+0

Alors vous avez terminé avec quelle solution? – Guillaume

+0

Je ne l'ai pas fait. Jamais été capable de tester ou d'obtenir quelque chose au travail. En fin de compte, j'ai fini par utiliser le code-first à long terme. –

Répondre

14

On m'a posé cette question à quelques reprises dans le passé. Il n'y a pas de moyen évident ou facile. C'est possible qu'il n'y en ait pas mais nous sommes des développeurs et il y a toujours un moyen! Est-ce que je sais ce que c'est? Puis-je imaginer des idées? .... Mmmm .. à l'exécution, le modèle est basé sur des classes fortement typées de l'espace de métadonnées. Vous pouvez les créer à la volée. Mais alors vous devez modifier le fichier xml du fichier edmx. Il y a LINQ to XML ou xpath pour cela. Modifier le schéma de la base de données ... comment model construit d'abord dbs ... il crée sql et ensuite vous l'exécutez. Vous devez créer sql (how? Shrug) et l'exécuter (objectcontext.executestorecommand()). Réalisable? Possible? Je n'ai aucune idée. Vraiment la réponse est non ... il n'y a rien dans VS ou .NET 4 (API EF) pour activer facilement cela autant que je sache. Sûrement quelqu'un de plus intelligent et patient que moi a été dépensé (gaspillé ??) beaucoup de temps (essayant de) déjouer EF pour arracher ça. Sur la base, cependant, de votre réponse à la suggestion sur le blog de Jeremy, vous cherchez quelque chose de intégré/maniable. C'est plus facile de répondre avec un "non".

julie

+7

Bienvenue à SO, Julie! – Yakimych

+0

Je pense qu'une combinaison de code-first avec 'ExpandoObject' pourrait le faire. Mais plutôt que de réifier les champs définis par l'utilisateur, il est plus logique de les traiter comme non standard de toute façon. +1 à Yakimych; Bienvenue! –

+0

Je suis d'accord que ce serait beaucoup plus facile avec le code d'abord et aucun modèle du tout, une couche de complexité et des règles pour traiter avec beaucoup de travail –

1

Jeremy Miller discute un ensemble similaire dans this article. Il utilise nHibernate, mais cela pourrait vous donner quelques idées.

+0

Oui, ça me donne quelques idées, dont aucune n'est simple. Je suis surpris que cette exigence ne soit pas commune avec nHibernate ou EF d'ailleurs. D'autres ressources ou idées? N'a pas vraiment répondu à la question juste fourni une référence, difficile de fermer la question pour cela. –

+0

J'ai pensé à faire cela mais mon scénario signifie que je dois permettre à l'utilisateur d'ajouter "employé" en premier lieu avant de définir les champs personnalisés ... dans un sens, même la table est personnalisée. – War

11

Il y a souvent plus d'une façon de résoudre un problème, et ce n'est pas une exception. Dans ce cas, ce que vous recherchez est de permettre aux utilisateurs d'ajouter de nouveaux champs à votre application et votre base de données et d'utiliser ces champs depuis votre application. Voici quelques façons de le faire:

a) Autoriser les utilisateurs à modifier le schéma de la base de données.
b) Créer une structure distincte pour définir les «champs définis par l'utilisateur» et y stocker des données.
c) Créer des champs «réservés» pouvant être annulés dans les tables où les utilisateurs sont plus susceptibles d'avoir besoin de leurs propres champs.

Je préfère l'approche (b) et parfois l'approche (c) lorsque des champs personnalisés définis par l'utilisateur sont nécessaires dans une application. Voici quelques-uns des avantages/inconvénients pour chacun des trois:

Modifier schéma

Risky: Si vous permettez aux utilisateurs de modifier le schéma de base de données, où tracer la ligne? S'ils peuvent ajouter des champs, ils peuvent aussi changer la définition de champs existants, ajouter ou supprimer des index, etc. Cela peut conduire à un cauchemar de support avec des bugs, des problèmes de performance, etc. déclenchés par des modifications de schémas effectuées par les utilisateurs.
Performant Performant: stocker les nouveaux champs définis par l'utilisateur en ligne dans des tables existantes aura généralement un avantage sur les performances par rapport à une structure séparée, mais seulement s'ils ne dépassent pas les limites avec des changements.
Clunky: EF détermine le schéma au moment de la conception. Pour que cela fonctionne au moment de l'exécution, vous devez générer de nouvelles classes d'entités à l'exécution avec des membres représentant les nouveaux champs et vous devez mettre à jour les métadonnées de mappage. runtime. Les classes d'entités générées à l'exécution peuvent hériter des classes générées au moment du design. Vous n'avez donc besoin que d'ajouter des membres et des mappages pour les nouveaux champs définis par l'utilisateur. Bien que possible, c'est maladroit. Le code qui consomme les classes générées par l'exécution doit utiliser la réflexion pour accéder aux nouveaux membres créés lors de l'exécution.

structure séparée

Convivial: En créant une structure séparée pour le stockage des champs personnalisés, vous pouvez créer une logique d'application pour les utilisateurs d'ajouter/supprimer ces champs, etc. Ils ne doivent pas nécessairement désordre avec la base de données, à la place, vous pouvez avoir des formulaires de maintenance dans l'application pour l'ajout de nouveaux champs.
Adapté aux EF: inutile de manipuler les classes d'entités et de mettre en correspondance les métadonnées au moment de l'exécution. Tout est défini au moment de la conception et les champs définis par l'utilisateur sont simplement des données.
Légèrement moins performant: Disposer de tables distinctes pour définir et stocker les champs définis par l'utilisateur peut rendre les recherches légèrement plus coûteuses en raison d'allers-retours supplémentaires ou de jointures supplémentaires.

Separate table structure for user defined fields

Les champs réservés

assez souvent: Dans de nombreuses situations, les champs personnalisés ne sont utilisés que pour un ou quelques champs supplémentaires. La réservation de quelques colonnes couvre souvent 99% des besoins des utilisateurs. Même un champ "remarques" générique dans chaque tableau est souvent suffisant dans les applications métier.
Limité: Si les utilisateurs veulent plus de champs que vous avez réservés, ou d'autres types de données que ceux que vous avez réservés, cela peut constituer une limitation.
Performant: Colonnes en ligne, récupérées sans boucles ou jointures supplémentaires.
Défini au moment de la conception: Aucune durée d'exécution liée aux définitions de type d'entité ou aux mappages.

Reserved fields

2

Brent me pingé sur Twitter aujourd'hui (presque 2 ans après ce post) pour voir si quelque chose a changé. Ce scénario n'est toujours pas pris en charge par EF. Cependant Rowan Miller a un message intéressant sur la façon de tirer cela avec Code First http://romiller.com/2012/03/26/dynamically-building-a-model-with-code-first/

Cela peut ou ne peut pas faire ce que vous avez besoin, mais cela vaut le coup d'oeil.

0

Ceci est une version de Reserved fields de @KristoferA réponse que j'ai utilisé dans le passé.

Vous pouvez ajouter une colonne XML (ou JSON) supplémentaire sur chaque table susceptible de nécessiter des données personnalisées, puis de les lire/écrire à partir de la base de données à l'aide de EF.Après lecture, désérialisez XML (JSON) et passez-le au mécanisme supposé gérer les mappages, puis présentez-le à l'utilisateur. Il en va de même pour l'écriture des données que vous lisez depuis l'interface utilisateur -> mapper vers l'objet -> sérialiser vers XML (JSON) -> et écrire dans ces champs supplémentaires.

Questions connexes