我正在使用ASP.NET Identity 2.0。目前,我希望将ApplicationUser
(已AspNetUsers
重命名为Users
)扩展到UserDetails
等表FirstName
。
我的问题是什么? 我已经分离了存储EF Model的类库项目。我不想生成另一个EF模型(如果没有必要的话)。
我在用户表和UserDetails
表之间存在SQL Server关系,这一切都没问题。不幸的是,在ASP项目中,Users表在IdentityUser
中进行了深度硬编码。这意味着我ApplicationUser
继承了IdentityUser
。
我在尝试AppDbContext
:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Ignore columns
builder.Entity<ApplicationUser>().Ignore(c => c.PhoneNumberConfirmed);
// Rename tables
builder.Entity<ApplicationUser>().ToTable("Users");
builder.Entity<IdentityRole>().ToTable("Roles");
builder.Entity<IdentityRoleClaim<string>>().ToTable("IdentityRoleClaims");
builder.Entity<IdentityUserClaim<string>>().ToTable("IdentityUserClaims");
builder.Entity<IdentityUserLogin<string>>().ToTable("IdentityUserLogins");
builder.Entity<IdentityUserToken<string>>().ToTable("IdentityUserTokens");
// Relationship
builder.Entity<ApplicationUser>()
.HasOne(p => p.UserDetails)
.WithOne(i => i.Users)
.HasForeignKey<Shared.Database.UserDetails>(u => u.UserID);
}
问题出在WithOne(i => i.Users)
的最后一行,i.Users
不是ApplicationUser
。有趣的是,ApplicationUser
具有与i.Users
相同的属性:D
所以我只需要知道如何正确地转换它以建立关系。
任何想法如何解决这个问题?或者任何建议如何以另一种方式做到这一点?
共享项目由1个额外项目(WCF)使用,因此我无法继承IdentityUser
:/
谢谢你们。
答案 0 :(得分:2)
我理解它的方式,您希望将两个不同的对象映射到同一个数据库表,并将另一个实体FK映射到该表。你对第一部分没有任何问题,但第二部分遇到了麻烦:
问题出在
WithOne(i => i.Users)
的最后一行,i.Users
不是ApplicationUser
。有趣的是,ApplicationUser
具有与i.Users
相同的属性:D
我看到两种解决方案。
UserDetails
课程中删除导航属性,只需在WithOne()
这两个地方使用。假设您当前在共享项目中的UserDetails
类如下所示:
public class UserDetails
{
public string Id { get; set; }
public string FirstName { get; set; }
// other properties ...
public string UserID { get; set; }
public User User { get; set; } // the problematic navigation property
}
您可以将其转换为通用类:
public class UserDetails<TUser> where TUser: class
{
public string Id { get; set; }
public string FirstName { get; set; }
// other properties ...
public string UserId { get; set; }
public TUser User { get; set; }
}
让旧的非泛型类简单地继承它:
public class UserDetails : UserDetails<User> { }
现在共享项目EF模型中的所有内容都应该像以前一样,因此使用它的其他(WCF)项目不应该受到影响。
我猜你已经明白了。在ASP项目中,您只需创建另一个类:
public class ApplicationUserDetails : UserDetails<ApplicationUser> { }
并将其映射到UserDetails
表格,类似于您将ApplicationUser
映射到Users
的方式:
builder.Entity<ApplicationUserDetails>().ToTable("UserDetails");
然后将UserDetails
类中的ApplicationUser
导航属性更改为:
public ApplicationUserDetails UserDetails { get; set; }
最后建立了没有任何问题的关系:
builder.Entity<ApplicationUser>()
.HasOne(u => u.UserDetails)
.WithOne(d => d.User)
.HasForeignKey<ApplicationUserDetails>(d => d.UserID);