我为“自动生成的”webpages_Membership表创建了一个模型,以便在用户丢失确认电子邮件以便能够重新发送时,我可以阅读ConfirmationToken。这是我在AccountModels.cs中的代码:
[Table("webpages_Membership")]
public class webpages_Membership
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public Nullable<DateTime> CreateDate { get; set; }
public string ConfirmationToken { get; set; }
public Nullable<bool> IsConfirmed { get; set; }
public Nullable<DateTime> LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
public string Password { get; set; }
public Nullable<DateTime> PasswordChangedDate { get; set; }
public string PasswordSalt { get; set; }
public string PasswordVerificationToken { get; set; }
public Nullable<DateTime> PasswordVerificationTokenExpirationDate { get; set; }
}
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<webpages_Membership> webpages_Membership { get; set; }
}
在创建此模型之前,我能够使用以下代码行在App_Start上插入单个用户:
if (Membership.Provider.GetUser("admin", false) == null)
{
((SimpleMembershipProvider)Membership.Provider).CreateUserAndAccount("admin", "bidchuck");
}
然而,在实现此模型之后,该行现在抛出异常:
[SqlException (0x80131904): Cannot insert explicit value for identity column in table 'webpages_Membership' when IDENTITY_INSERT is set to OFF.]
所以,我怀疑我的模型代码读取此表中的数据与WebSecurity自动生成表的方式有冲突,这是异常的原因。任何人都可以解释如何更改我的模型代码,以便WebSecurity可以自己的方式自动创建表吗?
或者,建议我实施“重新发送确认电子邮件”的其他方式
谢谢!
答案 0 :(得分:0)
问题在于:
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
你明确告诉EF这是一个标识列(即它应该为你生成一个id)。但是,UserId来自ASP.NET成员资格,因此您的表 实际上不会生成id。
注意:删除该行后,您必须进行迁移。
<强>更新强>
创建POCO以对表进行建模:
[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 ICollection<Role> Roles { get; set; }
[ForeignKey("UserId")]
public ICollection<OAuthMembership> OAuthMemberships { get; set; }
}
基本上只是对表格中的字段进行建模。这应该涵盖所有内容,但事情可能已经改变或者可能添加了不同的约束。 [Table("webpages_Membership")]
告诉EF要查找哪个表,因为名称或类不完全匹配。
将您的POCO连接到DbContext子类。您将需要使用与实际映射实体(您迁移的实体,使用更新数据库等)所使用的上下文不同的上下文。数据库初始化策略是在DbContext级别设置的,所以如果你把它添加到你用于其他一切的同一个,它会尝试迁移它,你最终会得到来自EF的讨厌错误。
public class SimpleMembershipContext : DbContext
{
public SimpleMembershipContext()
: base("name=YourConnectStringName")
{
// this tells EF to not worry about migrating or modifying the database
Database.SetInitializer<SimpleMembershipContext>(null);
}
public DbSet<Membership> Memberships { get; set; }
}
将“YourConnectionStringName”替换为项目数据库的连接字符串名称(在web.config中)。如果您将会员资料存储在其他地方,这也可能是一个完全不同的数据库。
现在,您可以像在任何其他实体中一样在代码中使用它:
var membershipDb = new SimpleMembershipContext();
var someMember = membershipDb.Memberships.Find(userId);