De manière dynamique l'évolution de schéma dans le Cadre de l'Entité de Base
UPD ici est la façon dont j'ai résolu le problème. Même si c'est probablement pas le meilleur, il a travaillé pour moi.
J'ai un problème avec le travail avec les EF de Base. Je veux séparer les données pour différentes sociétés dans mon projet de base de données via un schéma du mécanisme. Ma question est comment je peux changer le nom du schéma dans runtime? J'ai trouvé question similaire sur cette question, mais il est encore ananswered et j'ai quelques conditions différentes. J'ai donc Resolve
méthode qui accorde db-contexte si nécessaire
public static void Resolve(IServiceCollection services) {
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<DomainDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IOrderProvider, OrderProvider>();
...
}
Je peux définir un schéma nom dans OnModelCreating
, mais, comme l'a montré avant, cette méthode est appelée une seule fois, afin que je puisse régler le nom du schéma globalement ici comme ça
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("public");
base.OnModelCreating(modelBuilder);
}
ou la droite dans le modèle via un attribut comme ça
[Table("order", Schema = "public")]
public class Order{...}
Mais comment puis-je changer le nom du schéma dans runtime? J'ai créer ef du contexte pour chaque demande, mais tout d'abord je fugure de sortir du schéma de nom d'utilisateur par l'intermédiaire de la demande pour certains au schéma de la table partagée dans la base de données. Alors, quelle est la vraie manière d'organiser ce mécanisme:
- Comprendre le nom du schéma de l'utilisateur des informations d'identification;
- Obtenir des données spécifiques à l'utilisateur de la base de données de schéma spécifique.
Merci.
P. S.-je utiliser PostgreSql et c'est une raison de lowecased nom de la table.
Je l'ai fait, mais s'il vous plaît, prenez soin avec elle. stackoverflow.com/a/50529432/3272018
OriginalL'auteur user3272018 | 2016-09-14
Vous devez vous connecter pour publier un commentaire.
Avez-vous déjà utiliser EntityTypeConfiguration dans EF6?
Je pense que la solution serait d'utiliser la cartographie pour les entités sur la OnModelCreating méthode dans la classe DbContext, quelque chose comme ceci:
Le code sur OnConfiguring méthode des forces de l'exécution de MapProduct sur chaque création de l'instance de la classe DbContext.
Définition de MapProduct méthode:
Comme vous pouvez le voir ci-dessus, il y a une ligne pour définir le schéma et le nom de la table, vous pouvez envoyer un nom de schéma pour un constructeur dans DbContext ou quelque chose comme ça.
S'il vous plaît ne pas utiliser la magie des chaînes, vous pouvez créer une classe avec tous les schémas, par exemple:
Pour créer votre DbContext avec schéma spécifique, vous pouvez écrire ceci:
Évidemment, vous devez définir le nom du schéma selon le schéma du nom du paramètre valeur:
OnModelCreating
, le problème de cette méthode est appelée une seule fois, donc la prochaine créé le contexte qui va avoir le même schéma. Mais peut-être que j'ai manqué quelque chose d'important dans votre réponse?J'ai reçu votre point, vous avez raison, ma réponse précédente n'inclut pas la solution pour OnModelCreating problème, mais j'ai cherché sur les blogs une solution à ce problème et j'ai trouvé le code pour OnConfiguring méthode, j'ai modifié ma réponse s'il vous plaît vérifier et laissez-moi savoir si c'est utile lien
Cela peut fonctionner pour les petits projets, mais je ne peux pas imaginer le maintien de la MapProduct méthode pour des centaines de tableaux, de ne pas mentionner tous les paramètres possibles et les migrations...
Vous avez un bon point, tu parles de l'écriture de code pour les méthodes ou le maintien d'un grand fichiers de code?
OriginalL'auteur H. Herzl
Il ya un couple de façons de le faire:
DbContextOptionsBuilder.UseModel()
IModelCacheKeyFactory
service de avec un qui prend le schéma en compteJ'ai le même problème, il n'y a pas de documentation ou des échantillons de la façon de mettre en œuvre IModelCacheKeyFactory en EF de Base correctement.
Oh, finalement je l'ai fait. Je vais fournir ce code comme auto-réponse un peu plus tard. Je suis sûr que ce n'est pas un moyen idéal pour atteindre mon but, mais il fonctionne. Peut-être même que quelqu'un pourrait améliorer ma solution. Désolé je ne l'ai pas fait plus tôt.
Salut @user3272018 pouvez-vous partager votre solution avec nous ? Je suis en train de faire la même chose.
comme je l'ai mentionné dans la question, je l'ai déjà fait part de ma solution here
OriginalL'auteur bricelam
Je trouve ce blog pourrait être utile pour vous. Parfait !:)
https://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/
Ce blog est basé sur ef4, je ne suis pas sûr qu'il fonctionne parfaitement avec les objectifs ef de base.
L'idée principale de ces codes est de fournir une méthode statique pour créer différents DbContext par les différents schéma et de mettre en cache certains identificateurs.
OriginalL'auteur snys98
Désolé tout le monde, je devrais ai posté une solution avant, mais pour une raison que je ne l'ai pas, si elle est ici.
MAIS
Garder à l'esprit que tout ce qui pourrait être mal avec la solution car il ni a pas été examiné par personne, ni de la production a été, probablement, je vais obtenir des commentaires ici.
Dans le projet, j'ai utilisé ASP .NET de Base 1
Sur ma db structure. J'ai 2 contextes. La première contient des informations sur les utilisateurs (y compris la db régime, ils devraient adresse), le second contient des données spécifiques à l'utilisateur.
Dans
Startup.cs
- je ajouter les deux contextesAvis
UseInternalServiceProvider
partie, il a été suggéré par Nero Sule avec l'explication suivanteMaintenant nous avons besoin de
MultiTenantModelCacheKeyFactory
où
DomainDbContext
est le contexte avec des données spécifiques à l'utilisateurNous devons aussi changer un peu le contexte lui-même pour en faire un schéma courant:
et le contexte partagé est strictement liée à
shared
schéma:ICompanyProvider
est responsable de la gestion des utilisateurs nom de schéma. Et oui, je sais comment loin de l'idéal de code, il est.Et si je n'ai pas oublié quelque chose, c'est tout. Maintenant, dans chaque requête par un utilisateur authentifié, le contexte approprié sera utilisé.
J'espère que cela aide.
OriginalL'auteur user3272018
Vous pouvez utiliser l'attribut de Table sur le schéma fixe les tables.
Vous ne pouvez pas utiliser l'attribut de schéma de tables à langer et vous avez besoin de le configurer via ToTable API fluent.
Si vous désactivez le modèle de cache (ou vous écrivez votre propre cache), le schéma peut changer à chaque demande donc sur le contexte de création (tous les temps), vous pouvez spécifier le schéma.
C'est l'idée de base
Maintenant, vous pouvez avoir quelques différentes façons de déterminer le nom de schéma avant de créer le contexte.
Par exemple, vous pouvez avoir votre "système de tableaux" sur un contexte différent, donc sur chaque demande de récupérer le nom du schéma à partir du nom d'utilisateur en utilisant le système de tables et de créer l'environnement de travail sur le droit de schéma (vous pouvez partager des tables entre les contextes).
Vous pouvez avoir votre système de tables détachée du contexte et de les utiliser ADO .Net pour l'accès à eux.
Il y a probablement plusieurs autres solutions.
Vous pouvez aussi jeter un oeil ici
Multi-Locataire Avec le Premier Code EF6
et vous pouvez google
ef multi tenant
MODIFIER
Il y a aussi le problème du modèle de mise en cache (j'ai oublié qui).
Vous devez désactiver le modèle de mise en cache ou de modifier le comportement du cache.
OnModelCreating
méthode appelée une seule fois et je n'ai aucun moyen de changer le nom du schéma de via sur chaque demande. En fait j'utilise EF de Base, maisOnModelCreating
le comportement est le même. @bricelam a dit à propos de deux façons de résoudre mon problème, je suis donc intéressé par une explication plus détaillée, parce que EF du développeur doit savoir à propos de EF quelque chose de plus que d'autres l'homme, hmm?Dans la question que vous avez posté il y a
IDbModelCacheKeyProvider
qui semble similaire àIModelCacheKeyFactory
. C'est peut-être la clé pour résoudre mon problème. J'ai raté cet article-merci.Vous avez raison!!! J'ai oublié le modèle de mise en cache! Prenez également soin sur les performances (vous pouvez trouver quelques articles autour de, aussi sur Stack Overflow)
OriginalL'auteur bubi
peut-être que je suis un peu en retard pour cette réponse
mon problème était de la manipulation de schéma différent avec la même structure permet de dire multi-locataire.
Quand j'ai essayé de créer différentes instances d'un même contexte pour les différents schémas, Entité cadres 6 vient de jouer, attraper la première fois le dbContext a été créé puis pour les cas suivants ils ont été crée avec différents schémas de nom mais onModelCreating n'ont jamais été appelés ce qui signifie que chaque instance a été pointant vers le même auparavant exercé Pré-Vues", en pointant sur le premier schéma.
Puis j'ai réalisé que la création de nouvelles classes héritant de myDBContext un pour chaque schéma permettra de résoudre mon problème en surmontant entity Framework attraper problème de la création d'un nouveau contexte pour chaque schéma, mais ensuite vient le problème que nous nous retrouverons avec codé en dur schémas, à l'origine d'un autre problème en termes de code de l'évolutivité lorsque nous avons besoin d'ajouter un autre schéma, d'avoir à ajouter plus de classes et de rassembler et de publier une nouvelle version de l'application.
J'ai donc décidé d'aller un peu plus loin, à la création, à la compilation et à l'ajout de classes à la solution actuelle dans l'exécution.
Voici le code
J'espère que cela aide quelqu'un pour gagner du temps.
OriginalL'auteur Randy
Mise à jour pour le MVC de Base 2.1
Vous pouvez créer un modèle à partir d'une base de données avec plusieurs schémas. Le système est un peu schéma agnostique dans sa dénomination. Même nommé tables d'obtenir un "1" ajouté. "dbo" est l'hypothèse d'un schéma afin de ne pas ajouter quoi que ce soit, en préfixant le nom d'une table avec elle, le PM de commande
Vous devrez renommer le modèle des noms de fichiers et les noms de classe vous-même.
Dans le PM de la console
OriginalL'auteur pixelda