如何正确实现其他实体对身份用户的引用?
我正在使用具有自己的上下文的标识。如何正确实现其他实体对身份用户的引用?
public class ApplicationUser : IdentityUser {
// some custom fields
}
public class IdentityContext : IdentityDbContext<ApplicationUser> {
//...
}
我也有一些其他的东西,例如这个
public class Comment{
public int Id {get;set;}
public string Message{get;set;}
public DateTime Time{get;set;}
}
这是由我的其他方面
public class MyContext :DbContext {
public DbSet<Comment> Comments { get; set; }
//... other DbSets
}
问题使用
。我想,我的评论实体有author属性,所以我有这样的事情
public class Comment{
public int Id {get;set;}
public string Message{get;set;}
public DateTime Time{get;set;}
public virtual ApplicationUser Author {get;set;}
}
但ApplicationUser位于不同的背景下,虽然在同一个数据库中。我敢打赌这是不可能的。
如何正确执行此操作? 我应该移动DbSets从MyContext到IdentityContext,这样我就可以自由地使用这样的代码
public virtual ApplicationUser Author {get;set;}
或者我应该把它在不同的上下文,但添加类似
public string AuthorId {get;set}
,并提出一些解决方法每次需要时从不同的上下文中获取作者信息?或者是其他东西?
感谢
编辑
好吧,我结束了这样的事情:
public class ApplicationUser : IdentityUser {
public virtual UserProfile UserProfile { get; set; }
}
public class UserProfile {
[Key, ForeignKey("ApplicationUser")]
public string Id { get; set; }
//... custom fields
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class IdentityContext : IdentityDbContext<ApplicationUser> {
//...
public DbSet<UserProfile> UserProfiles { get; set; }
}
但是我应该如何实现评论的作者引用?喜欢这个?所以它不会通过EF关系链接,我只需在自己的代码中填充UserProfileId?
public class Comment{
public int Id {get;set;}
public string UserProfileId{get;set;}
}
这是正确的方法吗?
问自己问题,ApplicationUser有什么信息可用于您的商业模式?如果是这样,是存储它的正确位置吗?或者你只是想链接用户?
ApplicationUser位于不同的上下文中,但位于相同的数据库中。
但现在假设它不是。假设你将来想使用类似IdentityServer的东西。
我认为最好的办法是保持您的业务信息与身份信息分离。我不想将登录信息暴露给业务,并且可能会读取或更改其可能性。
我已经看到了ApplicationUser(作为业务上下文的一部分)在ViewModel中发送到客户端的代码,其中包括HashPassword。绝对是你想要阻止的事情。
你可以做的是在MyContext中添加一个用户表来存储你想要使用的数据。 ApplicationUser在您的业务模型中没有任何您想要的信息。
我假设你想要的只是将信息链接到用户。并且您想从Entiy Framework的对象链接中获益。
因此,创建一个用户表并向ApplicationUser添加一个属性来存储用户表的UserId。或者您可以通过其他方式链接:将ApplicationUserId添加到您的用户表中。也可以在两者中使用相同的Id:set ApplicationUser.Id(不一定是guid)或使用为User.Id生成的guid。
如果您想使用身份上下文中的某些附加信息,例如, EmailAddress,你可以考虑增加索赔。
- 更新 -
的想法是一个用户表添加到您的背景下,没有身份背景。为了更清楚我会打电话给表人(不是用户)。注意Person不会继承IdentyUser/ApplicationUser。
public class Person {
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
//etc..
public string ApplicationUserId { get; set; }
}
public class MyContext :DbContext {
public DbSet<Comment> Comments { get; set; }
public DbSet<Person> Persons { get; set; }
//... other DbSets
}
public class Comment{
public int Id {get;set;}
public string Message{get;set;}
public DateTime Time{get;set;}
public virtual Person Author {get;set;}
}
现在,当我查询当前用户,我可以查找的Person.Id所有评论(基于User.Identity.GetUserId())。
创建登录时,请不要忘记添加人员。
我希望这会有所帮助。如果没有,请让我知道。
实施例:
public class ApplicationUser : IdentityUser {
// some custom fields
}
public class Comment{
public int Id {get;set;}
public string Message{get;set;}
public DateTime Time{get;set;}
public string AuthorId {get;set}
[ForeignKey("AuthorId")]
public virtual ApplicationUser Author {get;set;}
}
public class MyContext :IdentityDbContext<ApplicationUser> {
public MyContext(): base("DefaultConnection", false){ }
public DbSet<Comment> Comments { get; set; }
//... other DbSets
}
我总是流动这种模式。希望它对你有所帮助。
谢谢,像这样的代码有效,但@Ruard van Elburg提到了一个非常有趣的想法 - 不在其他实体中使用ApplicationUser。虽然我还没有得到如何去做。 – uturupu
编辑该问题。你能再次看到代码吗?您的评论确实有道理,但我仍然不太了解如何将评论类实体与UserProfile链接起来。 – uturupu
谢谢。这可能是我想要的。所以我只要创建用户就设置ApplicationUserId。 – uturupu
不客气。请注意,你将需要这两个上下文。确保ApplicationUser和Person都被创建。您可以选择自己设置标识或使用ApplicationUser生成的标识。无论哪种方式使用该值Person.ApllicationUserId。 –