Fusionner MyDbContext avec IdentityDbContext
j'ai un MyDbContext dans un projet de bibliothèque de classe de couches de données séparées. Et j'ai un ASP.NET projet MVC 5 avec un contexte Identitydb par défaut. Les deux contextes utilisent la même base de données, et je veux utiliser la table Aspnetusters à clé étrangère pour certaines de mes tables. Donc je voudrais fusionner les deux contextes, et je veux utiliser ASP.NET L'identité aussi.
Comment faire?
s'il vous Plaît des conseils, des
C'est mon contexte après Fusion:
public class CrmContext : IdentityDbContext<CrmContext.ApplicationUser> //DbContext
{
public class ApplicationUser : IdentityUser
{
public Int16 Area { get; set; }
public bool Holiday { get; set; }
public bool CanBePublic { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public CrmContext()
: base("DefaultConnection")
{
}
public DbSet<Case> Case { get; set; }
public DbSet<CaseLog> CaseLog { get; set; }
public DbSet<Comment> Comment { get; set; }
public DbSet<Parameter> Parameter { get; set; }
public DbSet<Sign> Sign { get; set; }
public DbSet<Template> Template { get; set; }
public DbSet<Read> Read { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
voici ma classe RepositoryBase:
public class RepositoryBase<TContext, TEntity> : IRepositoryBaseAsync<TEntity>, IDisposable
where TContext : IdentityDbContext<CrmContext.ApplicationUser> //DbContext
where TEntity : class
{
private readonly TContext _context;
private readonly IObjectSet<TEntity> _objectSet;
protected TContext Context
{
get { return _context; }
}
public RepositoryBase(TContext context)
{
if (context != null)
{
_context = context;
//Here it is the error:
_objectSet = (_context as IObjectContextAdapter).ObjectContext.CreateObjectSet<TEntity>();
}
else
{
throw new NullReferenceException("Context cannot be null");
}
}
}
une exception du type 'System.Data.Entity.ModelConfiguration.ModelValidationException'
s'est produite dans Entitefram Framework.dll mais n'a pas été traité par l'utilisateur code
informations supplémentaires : une ou plusieurs erreurs de validation ont été détectées lors de la génération du modèle:
mise à jour: j'ai trouvé la solution.
j'ai dû supprimer cette convention d'appellation:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
et migrer le modèle EF cf en db, pour renommer mes tables avec les conventions de nameing de asp.net identité. Il travaille maintenant!
7 réponses
- déplacez la définition
ApplicationUser
à votre lad. - héritez de votre
MyDbContext
deIdentityDbContext<ApplicationUser>
ouIdentityDbContext
- OnModelCreating - Fournir la clé étrangère info.
- Pass
MyDbContext
tout en créant leUserManager<ApplicationUser>
vous pouvez recevoir le message suivant si vous suivez les étapes ci-dessus, mais ne pouvez pas trouver comment fournir l'information clé. L'erreur que vous pouvez recevoir est:
IdentityUserLogin:: EntityType 'IdentityUserLogin' n'a pas de clé définie. Définissez la clé pour ce type D'entité. Cadre.IdentityUserRole:: EntityType "IdentityUserRole" n'a pas de clé définie. Définissez la clé pour ce type D'entité.
créer les deux classes suivantes
public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin>
{
public IdentityUserLoginConfiguration()
{
HasKey(iul => iul.UserId);
}
}
public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
{
public IdentityUserRoleConfiguration()
{
HasKey(iur => iur.RoleId);
}
}
dans la méthode OnModelCreating dans vos Applications DbContext ajouter les deux configurations décrites ci-dessus au modèle:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration());
modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration());
}
cela devrait maintenant se débarrasser des méthodes d'erreur lorsque votre modèle est créé. Il l'a fait pour moi.
cela peut être un vieux fil, mais cet article a été très utile pour montrer comment obtenir la solution à la question ci-dessus fonctionne: http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx
je n'ai fin de devoir inclure
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//....
}
parce que sans elle, j'obtiendrais l'erreur suivante:
EntityType 'IdentityUserRole' n'a pas de clé. Définissez la clé pour ce type D'entité. EntityType 'IdentityUserLogin' n'a pas de clé définie. Définissez la clé pour ce type D'entité. EntitySet ' IdentityUserRoles 'est basé sur le type' IdentityUserRole ' qui n'a pas de clés définies. EntitySet ' IdentityUserLogins 'est basé sur le type' IdentityUserLogin ' qui n'a pas de clés définies.
si j'ajoute ces configurations comme indiqué ci-dessus:
public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin>
{
public IdentityUserLoginConfiguration()
{
HasKey(iul => iul.UserId);
}
}
public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
{
public IdentityUserRoleConfiguration()
{
HasKey(iur => iur.RoleId);
}
}
il créerait un clé étrangère appelée Application_User.
1) après que vous héritez le contexte de Identitydb les erreurs contextuelles liées aux clés primaires sur les tables D'identité (AspNetUsers etc) devraient disparaître.
2) Votre extension ApplicationUser D'IdentityUser manque des propriétés de navigation qui sont interprétées comme des clés étrangères par le cadre D'entité (celles-ci sont également très utiles pour la navigation à partir de votre code).
public class ApplicationUser : IdentityUser
{
public Int16 Area { get; set; }
public bool Holiday { get; set; }
public bool CanBePublic { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
//*** Add the following for each table that relates to ApplicationUser (here 1-to-many)
public virtual IList<Case> Cases { get; set; } //Navigation property
//*** and inside the case class you should have
//*** both a public ApplicationUser ApplicationUser {get;set;}
//*** and a public string ApplicationUserId {get;set;} (string because they use GUID not int)
}
3) j'ai lu dans de nombreux endroits que lors de surimpression sur Modelcreating, vous devez appeler la méthode de base. On dirait que parfois on peut s'en passer.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//....
}
j'ai donné une réponse complète à cette question ici . Voici la réponse courte:
basé sur le code source IdentityDbContext si nous voulons fusionner IdentityDbContext avec notre DbContext nous avons deux options:
première Option:
Créer un DbContext qui hérite de IdentityDbContext et a accès aux classes.
public class ApplicationDbContext
: IdentityDbContext
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
static ApplicationDbContext()
{
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
// Add additional items here as needed
}
deuxième Option: (Non recommandé)
En fait, nous n'avons pas à hériter du contexte Identitydb si nous écrivons tout le code nous-mêmes.
Donc, fondamentalement, nous pouvons juste hériter de DbContext et mettre en œuvre notre version personnalisée de "OnModelCreating(ModelBuilder builder) "du IdentityDbContext code source
le problème a été causé parce que vous avez exagéré le contenu de la méthode" OnModelCreating " qui est mis en œuvre dans la classe IdentityUser.
vous devez d'abord utiliser la méthode OnModelCreating de la classe de base, puis ajouter votre code. Votre méthode de création de Modèles devrait donc ressembler à ceci:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
j'ai essayé une façon simple.. copiez la chaîne de connexion à partir de votre base de données et remplacez la chaîne de connexion de DefaultConnection. Allez-y et créez l'utilisateur, toutes les tables nécessaires sont automatiquement créées dans votre base de données.
L'espoir qui aide