我正在尝试将SimpleMembership表与我的对象模型的其余部分集成 - 以管理来自单个数据库和上下文的所有实体。
到目前为止,我找到了手动旋转SM表的最佳配方(将SimpleMember与我的对象模型的其余部分结合起来的入口点)here.但是,如评论部分所述提供的代码示例中有几个错误。评论试图提供更正,但由于格式化,很难遵循。
我80%的方式在那里,但却陷入了Membership表的外键生成。 OnModelCreating块中的代码是否属于MyDbContext类?我在.WithMany(u => u.Members)行上遇到编译错误。
Membership.cs
[Table("webpages_Membership")]
public class Membership
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserId { get; set; }
public DateTime? CreateDate { get; set; }
[StringLength(128)]
public string ConfirmationToken { get; set; }
public bool? IsConfirmed { get; set; }
public DateTime? LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
[Required, StringLength(128)]
public string Password { get; set; }
public DateTime? PasswordChangedDate { get; set; }
[Required, StringLength(128)]
public string PasswordSalt { get; set; }
[StringLength(128)]
public string PasswordVerificationToken { get; set; }
public DateTime? PasswordVerificationTokenExpirationDate { get; set; }
<strike>public virtual ICollection<Role> Roles { get; set; }</strike>
编辑:最初我添加了上面的一行,以便在下面的无关代码块中删除编译器投诉。删除此创建FK到角色的尝试将对齐此代码的其余部分,以便这些模型类创建一个为SM生成表的迁移。
OAuthMembership.cs
[Table("webpages_OAuthMembership")]
public class OAuthMembership
{
[Key, Column(Order = 0), StringLength(30)]
public string Provider { get; set; }
[Key, Column(Order = 1), StringLength(100)]
public string ProviderUserId { get; set; }
public int UserId { get; set; }
}
Role.cs
[Table("webpages_Roles")]
public class Role
{
[Key]
public int RoleId { get; set; }
[StringLength(256)]
public string RoleName { get; set; }
public virtual ICollection<UserProfile> UserProfiles { get; set; }
}
UserProfile.cs
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
MyDbContext.cs
public MyDbContext() :base(“DefaultConnection”) { }
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<Membership> Membership { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<OAuthMembership> OAuthMembership { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserProfile>()
.HasMany<Role>(r => r.Roles)
.WithMany(u => u.UserProfiles)
.Map(m =>
{
m.ToTable("webpages_UsersInRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
编辑:下面的块包含在文章的一条评论中,但似乎不需要。
//modelBuilder.Entity<Membership>()
// .HasMany<Role>(r => r.Roles)
// .WithMany(u => u.Members)
// .Map(m =>
// {
// m.ToTable("webpages_UsersInRoles");
// m.MapLeftKey("UserId");
// m.MapRightKey("RoleId");
// });
}
}
答案 0 :(得分:3)
我按照文章中的说明进行操作,并且还考虑了以某种方式表明文章错误的评论。
我最终得到了以下课程:
<强> UserProfile.cs 强>
[Table("UserProfile")]
public class UserProfile
{
[Key, ForeignKey("Membership")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public ICollection<WebSecurity.Role> Roles { get; set; }
public WebSecurity.Membership Membership { get; set; }
}
您应该立即注意我在UserId列上使用的“ForeignKey”属性。由于用户首先在Membership表中创建,因此我的UserProfile表是从属表。
<强> Membership.cs 强>
[Table("webpages_Membership")]
public class Membership
{
//public Membership()
//{
// Roles = new List<Role>();
// OAuthMemberships = new List<OAuthMembership>();
//}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserId { get; set; }
public DateTime? CreateDate { get; set; }
[StringLength(128)]
public string ConfirmationToken { get; set; }
public bool? IsConfirmed { get; set; }
public DateTime? LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
[Required, StringLength(128)]
public string Password { get; set; }
public DateTime? PasswordChangedDate { get; set; }
[Required, StringLength(128)]
public string PasswordSalt { get; set; }
[StringLength(128)]
public string PasswordVerificationToken { get; set; }
public DateTime? PasswordVerificationTokenExpirationDate { get; set; }
public UserProfile UserProfile { get; set; }
}
Per Richard在文章中的评论中,我注释掉了构造函数。我还创建了一个返回UserProfile的引用,但没有创建角色。
<强> OAuthMembership.cs 强>
[Table("webpages_OAuthMembership")]
public class OAuthMembership
{
[Key, Column(Order = 0), StringLength(30)]
public string Provider { get; set; }
[Key, Column(Order = 1), StringLength(100)]
public string ProviderUserId { get; set; }
public int UserId { get; set; }
//[Column("UserId"), InverseProperty("OAuthMemberships")]
//public Membership User { get; set; }
}
我的OAuthMembership课程基本保持不变;根据理查德在文章中的评论,我只注释了用户属性。
<强> AccountModel.cs + UsersContext 强>
最后是UserContext类,我在其中为UsersInRoles表创建关联。
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<InternetApplication.Models.WebSecurity.Role>()
.HasMany<InternetApplication.Models.UserProfile>(r => r.UserProfiles)
.WithMany(u => u.Roles)
.Map(m =>
{
m.ToTable("webpages_UsersInRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
}
public DbSet<WebSecurity.Membership> Membership { get; set; }
public DbSet<WebSecurity.OAuthMembership> OAuthMembership { get; set; }
public DbSet<WebSecurity.Role> Roles { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
}
除了添加UsersInRoles映射外,我还为每个表添加了DbSet条目。
现在已经创建了所有内容,我可以使用添加迁移和更新数据库命令,并使用以下代码片段,其中包含Membership,UserProfile和角色表:
using (var db = new UsersContext())
{
var memberships = db.Membership
.Include("UserProfile")
.Include("UserProfile.Roles")
.ToList();
foreach (var member in memberships)
{
member.IsConfirmed = true;
}
db.SaveChanges();
}
这是一篇很长的帖子,但我希望有所帮助。
答案 1 :(得分:1)
我使用this question的答案从我数据库中现有的'webpage_'表中自动生成模型。这可确保以与SimpleMembership创建模型完全相同的方式创建模型。这导致了以下代码:
public partial class webpages_Membership
{
public int UserId { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public string ConfirmationToken { get; set; }
public Nullable<bool> IsConfirmed { get; set; }
public Nullable<System.DateTime> LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
public string Password { get; set; }
public Nullable<System.DateTime> PasswordChangedDate { get; set; }
public string PasswordSalt { get; set; }
public string PasswordVerificationToken { get; set; }
public Nullable<System.DateTime> PasswordVerificationTokenExpirationDate { get; set; }
}
public partial class webpages_Roles
{
public webpages_Roles()
{
this.webpages_UsersInRoles = new HashSet<webpages_UsersInRoles>();
}
public int RoleId { get; set; }
public string RoleName { get; set; }
public virtual ICollection<webpages_UsersInRoles> webpages_UsersInRoles { get; set; }
}
public partial class webpages_UsersInRoles
{
public int UserId { get; set; }
public int RoleId { get; set; }
public virtual webpages_Roles webpages_Roles { get; set; }
}
internal partial class MembershipMapping : EntityTypeConfiguration<webpages_Membership>
{
public MembershipMapping()
{
this.HasKey(t => t.UserId);
this.ToTable("webpages_Membership");
this.Property(t => t.UserId).HasColumnName("UserId").HasDatabaseGeneratedOption(new Nullable<DatabaseGeneratedOption>(DatabaseGeneratedOption.None));
this.Property(t => t.CreateDate).HasColumnName("CreateDate");
this.Property(t => t.ConfirmationToken).HasColumnName("ConfirmationToken").HasMaxLength(128);
this.Property(t => t.IsConfirmed).HasColumnName("IsConfirmed");
this.Property(t => t.LastPasswordFailureDate).HasColumnName("LastPasswordFailureDate");
this.Property(t => t.PasswordFailuresSinceLastSuccess).HasColumnName("PasswordFailuresSinceLastSuccess");
this.Property(t => t.Password).HasColumnName("Password").IsRequired().HasMaxLength(128);
this.Property(t => t.PasswordChangedDate).HasColumnName("PasswordChangedDate");
this.Property(t => t.PasswordSalt).HasColumnName("PasswordSalt").IsRequired().HasMaxLength(128);
this.Property(t => t.PasswordVerificationToken).HasColumnName("PasswordVerificationToken").HasMaxLength(128);
this.Property(t => t.PasswordVerificationTokenExpirationDate).HasColumnName("PasswordVerificationTokenExpirationDate");
}
}
internal partial class RolesMapping : EntityTypeConfiguration<webpages_Roles>
{
public RolesMapping()
{
this.HasKey(t => t.RoleId);
this.ToTable("webpages_Roles");
this.Property(t => t.RoleId).HasColumnName("RoleId");
this.Property(t => t.RoleName).HasColumnName("RoleName").IsRequired().HasMaxLength(256);
}
}
internal partial class UsersInRolesMapping : EntityTypeConfiguration<webpages_UsersInRoles>
{
public UsersInRolesMapping()
{
this.HasKey(t => new { t.UserId, t.RoleId });
this.ToTable("webpages_UsersInRoles");
this.Property(t => t.UserId).HasColumnName("UserId").HasDatabaseGeneratedOption(new Nullable<DatabaseGeneratedOption>(DatabaseGeneratedOption.None));
this.Property(t => t.RoleId).HasColumnName("RoleId").HasDatabaseGeneratedOption(new Nullable<DatabaseGeneratedOption>(DatabaseGeneratedOption.None));
this.HasRequired(t => t.webpages_Roles).WithMany(t => t.webpages_UsersInRoles).HasForeignKey(d => d.RoleId);
}
}
public class MembershipContext : DbContext, IDisposable
{
public DbSet<webpages_Membership> Membership { get; set; }
public DbSet<webpages_Roles> Roles { get; set; }
public DbSet<webpages_UsersInRoles> UsersInRoles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MembershipMapping());
modelBuilder.Configurations.Add(new RolesMapping());
modelBuilder.Configurations.Add(new UsersInRolesMapping());
base.OnModelCreating(modelBuilder);
}
}
请注意,我已排除了OAuthMembership表,因为我的解决方案并不需要它。但是,如果您按照我上面提供的链接中的步骤操作,您也可以轻松地包含该表格。
答案 2 :(得分:0)
从空白的MVC4 Internet模板开始我运行项目以便在新的数据库中创建SimpleMembership表 - 然后使用EF的反向工程师工具从这些表创建POCO。逐行逐步查找错误并在OP中编辑代码块。
使用该代码后,我使用了Package Manager来&#39; Add-Migration&#39; 和&#39; Update-Database&#39; 。初步测试证实一切正常 - 我想如果我找到暴露任何更深层次问题的边缘案例,我将不得不重新审视。