我有一个使用Identity 2的MVC 5 / EF 6数据库优先应用程序。默认的Identity模型已被修改为包括UserRoles和一些自定义属性,这些属性映射到我添加到AspNetUsers的列中-到目前为止,一切都工作得很好。
我有一个新要求,即向AspNetUsers添加多对多关系,称为AspNetUserAgreements。我已将表和外键添加到数据库中。
CREATE TABLE [dbo].[Agreement](
[AgreementID] [int] IDENTITY(1,1) NOT NULL,
[HTML] [varchar](max) NULL,
[Brief] [varchar](500) NULL,
[CreateDate] [datetime] NOT NULL CONSTRAINT [DF_Agreement_CreateDate] DEFAULT (getdate()),
[ChangeDate] [datetime] NULL,
[Active] [bit] NOT NULL CONSTRAINT [DF_Agreement_Active] DEFAULT ((1)),
[UserId] [nvarchar](128) NULL,
[Name] [varchar](50) NULL,
CONSTRAINT [PK_Agreement] PRIMARY KEY CLUSTERED
(
[AgreementID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Agreement] WITH CHECK ADD CONSTRAINT [FK_Agreement_AspNetUsers] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
GO
ALTER TABLE [dbo].[Agreement] CHECK CONSTRAINT [FK_Agreement_AspNetUsers]
GO
CREATE TABLE [dbo].[AspNetUserAgreement](
[UserId] [nvarchar](128) NOT NULL,
[AgreementID] [int] NOT NULL,
CONSTRAINT [PK_AspNetUserAgreement] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[AgreementID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AspNetUserAgreement] WITH CHECK ADD CONSTRAINT [FK_AspNetUserAgreement_Agreement] FOREIGN KEY([AgreementID])
REFERENCES [dbo].[Agreement] ([AgreementID])
GO
ALTER TABLE [dbo].[AspNetUserAgreement] CHECK CONSTRAINT [FK_AspNetUserAgreement_Agreement]
GO
ALTER TABLE [dbo].[AspNetUserAgreement] WITH CHECK ADD CONSTRAINT [FK_AspNetUserAgreement_AspNetUsers] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
GO
ALTER TABLE [dbo].[AspNetUserAgreement] CHECK CONSTRAINT [FK_AspNetUserAgreement_AspNetUsers]
GO
我有一个协议记录,一个AspNetUser记录和一个与它们相关的aspnetUserAgreement记录。这3个表已导入EF模型,我可以从AspNetUer实体中看到协议列表,还可以从Agreement实体中看到AspNetUsers列表。
ApplicationDbContext OnModelCreating具有以下功能:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<AspNetUser>()
.ToTable("AspNetUser")
.HasKey(d => d.Id)
.HasMany(d => d.UserAgreements)
.WithMany(d => d.AspNetUsers)
.Map(m =>
{
m.MapLeftKey("Id");
m.MapRightKey("AgreementID");
});
modelBuilder.Entity<ApplicationUser>()
.HasMany(d => d.UserAgreements)
.WithMany(d => d.ApplicationUsers)
.Map(m =>
{
m.MapLeftKey("Id");
m.MapRightKey("AgreementID")
});
modelBuilder.Entity<ApplicationUserRole>()//.ToTable("ApplicationUserRole")
.HasKey(ur => new { ur.UserId, ur.RoleId });
modelBuilder.Entity<ApplicationUserRole>()
.HasRequired(r => r.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId);
modelBuilder.Entity<ApplicationUserRole>()//.ToTable("ApplicationRole")
.HasRequired(ur => ur.User)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId);
base.OnModelCreating(modelBuilder);
}
ApplicationUser具有:
public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
{
public ApplicationUser()
{
UserAgreements = new HashSet<Agreement>();
UserRoles = new List<ApplicationUserRole>();
Id = Guid.NewGuid().ToString();
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
if (MemberDirectoryID.HasValue)
{
userIdentity.AddClaim(new Claim("Toolbar", this.Toolbar));
userIdentity.AddClaim(new Claim("HasSignedAgreement", this.HasSignedAgreement.ToString()));
//userIdentity.AddClaim(new Claim("NewMemberTemporaryGUID", this.NewMemberTemporaryGUID));
return userIdentity;
}
public string Toolbar
{
get
{
return ((List<ApplicationUserRole>)UserRoles).Any(a => a.Role.Name == "Admin") ? "admin" : "member";
}
}
public bool HasSignedAgreement
{
get
{
return ((HashSet<Agreement>)UserAgreements).Any();
}
}
public ICollection<ApplicationUserRole> UserRoles { get; set; }
public ICollection<Agreement> UserAgreements { get; set; }
}
协议实体是由EF创建的,但是我有这个分部类来对其进行扩展:
public interface IAgreement
{
}
[MetadataType(typeof(IAgreement))]
public partial class Agreement : IAgreement
{
public virtual ICollection<ApplicationUser> ApplicationUsers { get; set; } = new HashSet<ApplicationUser>();
}
我需要身份代码以返回我的ApplicationUser以及包含“协议”的UserAgreements列表。最初必须在登录时完成此操作,因为有一个自定义过滤器属性,该属性检查UserAgreements的数量,然后根据值定向User。
问题陈述::在调用Identity时,对象似乎结构正确,即我的ApplicationUser有一个称为UserAgreements的协议集合,但为空。没有错误,没有数据。协议永远不会加载...我必须缺少一些东西,因为如果我调用模型上下文,我可以从AspNetUser获取协议,而我可以从协议获取ApplicationUsers。
任何帮助表示感谢,谢谢!