2017-05-06 72 views
1

我正在使用具有自己的上下文的标识。如何正确实现其他实体对身份用户的引用?

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;} 
} 

这是正确的方法吗?

回答

3

问自己问题,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())。

创建登录时,请不要忘记添加人员。

我希望这会有所帮助。如果没有,请让我知道。

+0

编辑该问题。你能再次看到代码吗?您的评论确实有道理,但我仍然不太了解如何将评论类实体与UserProfile链接起来。 – uturupu

+0

谢谢。这可能是我想要的。所以我只要创建用户就设置ApplicationUserId。 – uturupu

+0

不客气。请注意,你将需要这两个上下文。确保ApplicationUser和Person都被创建。您可以选择自己设置标识或使用ApplicationUser生成的标识。无论哪种方式使用该值Person.ApllicationUserId。 –

0

实施例:

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 
} 

我总是流动这种模式。希望它对你有所帮助。

+0

谢谢,像这样的代码有效,但@Ruard van Elburg提到了一个非常有趣的想法 - 不在其他实体中使用ApplicationUser。虽然我还没有得到如何去做。 – uturupu