3

我正在尝试将 SimpleMembership 表与我的对象模型的其余部分集成 - 以管理来自单个数据库和上下文的所有实体。

到目前为止,我找到的用于手动启动 SM 表的最佳方法(将 SimpleMember 与我的对象模型的其余部分结合起来的入口点)可以在这里找到。但是,正如评论部分所引用的,所提供的代码示例中存在一些错误。评论试图提供更正,但由于格式化,很难理解。

我已经完成了 80% 的工作,但被会员表的外键生成卡住了。OnModelCreating 块中的代码是否属于 MyDbContext 类?我在 .WithMany(u => u.Members) 行上遇到编译错误。

会员资格.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; }
}

角色.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; }
}

用户配置文件.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

公共 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");
    //    });

}

}

4

3 回答 3

3

我按照文章中的说明进行操作,并且还考虑到了一些建议文章错误的评论。

我结束了以下课程:

用户配置文件.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 表是从属表。

会员资格.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; }
}

根据 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 类基本保持不变;根据 Richard 在文章中的评论,我只注释掉了 User 属性。

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 条目。

现在一切都已创建,我可以使用我的Add-MigrationUpdate-Database命令,并使用以下结合了 Membership、UserProfile 和 Roles 表的代码片段:

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();
}

这是一个很长的帖子,但我希望对您有所帮助。

于 2013-04-05T14:46:05.910 回答
1

我使用这个问题的答案从我的数据库中现有的“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 表,因为我的解决方案不需要它。但是,如果您按照我上面提供的链接中的步骤操作,您也可以轻松地包含该表。

于 2013-06-26T17:55:22.307 回答
0

从一个空白的 MVC4 Internet 模板开始,我运行该项目以便在一个新的数据库中创建 SimpleMembership 表 - 然后使用 EF 的逆向工程师工具从这些表中创建 POCO。逐行逐行查找错误并在 OP 中编辑代码块。

有了该代码,我使用 Package Manager 来'Add-Migration''Update-Database'。初步测试确认一切正常 - 我想如果我发现暴露任何更深层次问题的边缘情况,我将不得不重新审视。

于 2013-03-20T19:46:14.213 回答