I want to have my IdentityUser derived class to reference some data present on a detail table. In order to do so I created an extended IdentityUser that has a reference to an external detail table, and configured the IdentityDbContext accordingly so that the corresponding table is created.
我希望我的IdentityUser派生类引用明细表上的一些数据。为此,我创建了一个扩展的IdentityUser,它具有对外部细节表的引用,并相应地配置了IdentityDbContext,以便创建相应的表。
public class ApplicationUser : IdentityUser
{
public ICollection<PublishingContext> PublishingContexts { get; set; }
public ApplicationUser()
{
PublishingContexts = new List<PublishingContext>();
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class PublishingContext
{
public string UserId { get; set; }
public string Name { get; set; }
public string Uri { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public virtual IDbSet<PublishingContext> PublishingContexts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>()
.HasMany(u => u.PublishingContexts).WithRequired().HasForeignKey(ul => ul.UserId);
modelBuilder.Entity<PublishingContext>()
.HasKey(c => new { c.UserId, c.Name });
}
}
The problem is that even if the PublishingContexts table gets created and I manually fill some data onto it, I cannot manage to read the corresponding values back while logging in. I think that I need to configure the new table somewhere else on the system, but I'm currently stuck. Any suggestions?
问题是,即使publishingcontext表被创建,我手动填充一些数据到它上面,我也无法在登录时读取相应的值。我想我需要在系统的其他地方配置新表,但是我现在被卡住了。有什么建议吗?
1 个解决方案
#1
2
I think I figured it out. You need to define a custom UserStore that will redefine the FindBy methods, including the details table accordingly.
我想我算出来了。您需要定义一个自定义UserStore,它将重新定义FindBy方法,包括相应的details表。
public class ApplicationUserStore : UserStore<ApplicationUser>
{
public ApplicationUserStore() : this(new IdentityDbContext())
{
DisposeContext = true;
}
public ApplicationUserStore(DbContext context) : base(context)
{
}
public override Task<ApplicationUser> FindByIdAsync(string userId)
{
return GetUserAggregateAsync(u => u.Id.Equals(userId));
}
public override Task<ApplicationUser> FindByNameAsync(string userName)
{
return GetUserAggregateAsync(u => u.UserName.ToUpper() == userName.ToUpper());
}
Task<ApplicationUser> GetUserAggregateAsync(Expression<Func<ApplicationUser, bool>> filter)
{
return Users.Include(u => u.Roles)
.Include(u => u.Claims)
.Include(u => u.Logins)
.Include(u => u.PublishingContexts)
.FirstOrDefaultAsync(filter);
}
}
This is taken directly from Identity 2 sources. Basically I just added the .Include clause on the GetUserAggregateAsync method, which I had to redefine because it is private on the base class. Once you do that you will have to tell the system to use your userstore, by changing it on the IdentityConfig.cs file in App_Start
这是直接从身份2来源。基本上,我只是在GetUserAggregateAsync方法上添加了. include子句,我必须重新定义它,因为它在基类上是私有的。一旦您这样做了,您就必须通过在IdentityConfig中修改userstore来告诉系统使用它。在App_Start cs文件
var manager = new ApplicationUserManager(new ApplicationUserStore(
context.Get<ApplicationDbContext>()));
#1
2
I think I figured it out. You need to define a custom UserStore that will redefine the FindBy methods, including the details table accordingly.
我想我算出来了。您需要定义一个自定义UserStore,它将重新定义FindBy方法,包括相应的details表。
public class ApplicationUserStore : UserStore<ApplicationUser>
{
public ApplicationUserStore() : this(new IdentityDbContext())
{
DisposeContext = true;
}
public ApplicationUserStore(DbContext context) : base(context)
{
}
public override Task<ApplicationUser> FindByIdAsync(string userId)
{
return GetUserAggregateAsync(u => u.Id.Equals(userId));
}
public override Task<ApplicationUser> FindByNameAsync(string userName)
{
return GetUserAggregateAsync(u => u.UserName.ToUpper() == userName.ToUpper());
}
Task<ApplicationUser> GetUserAggregateAsync(Expression<Func<ApplicationUser, bool>> filter)
{
return Users.Include(u => u.Roles)
.Include(u => u.Claims)
.Include(u => u.Logins)
.Include(u => u.PublishingContexts)
.FirstOrDefaultAsync(filter);
}
}
This is taken directly from Identity 2 sources. Basically I just added the .Include clause on the GetUserAggregateAsync method, which I had to redefine because it is private on the base class. Once you do that you will have to tell the system to use your userstore, by changing it on the IdentityConfig.cs file in App_Start
这是直接从身份2来源。基本上,我只是在GetUserAggregateAsync方法上添加了. include子句,我必须重新定义它,因为它在基类上是私有的。一旦您这样做了,您就必须通过在IdentityConfig中修改userstore来告诉系统使用它。在App_Start cs文件
var manager = new ApplicationUserManager(new ApplicationUserStore(
context.Get<ApplicationDbContext>()));