如何为域实体和用户标识使用单个上下文



我正在进行一个小型的asp.net核心项目,在那里我将EF核心与SQL server结合使用。

到目前为止,我有以下配置:

  1. 我的域实体的Db上下文:
public class AppDbContext: DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Request> Requests { get; set; }
public DbSet<Ticket> Tickets { get; set; }
public DbSet<Project> Project { get; set; }
public DbSet<QA> QA { get; set; }
public DbSet<ProjectOwner> ProjectOwner { get; set; }
}
  1. AppIdentityDbContext由Visual Studio自动构建:

public class AppIdentityDbContext : IdentityDbContext
{
public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options)
: base(options)
{ }
public DbSet<IdentityUser> User { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}

我可以把这些上下文放在一个上下文中吗?据我所知,它们继承自不同的基本上下文,所以到目前为止,我的解决方案依赖于两个独立的上下文。我不确定保留两个上下文而不是一个上下文是否有任何好处,尤其是在小型应用程序的情况下。看完这篇文章后,我认为我的解决方案不需要两个。作为一个初学者,我想保持超级简单,那么我该如何实现呢?

非常感谢!

您可以将应用程序DbContext建立在IdentityDbContext的基础上,以提供标准EF集成身份验证,或者提供使用常规基于DbContext的应用程序上下文的自己的身份验证实现。然而,我一般建议将这些关切分开处理。这是一个使用有界DbContext的示例。IdentityDbContext实现了它的目的,而不会因应用程序数据的问题而污染它。尽管你可能经常想";链接";数据行发送给用户(即CreatedBy/ModifiedBy(,这就提出了让用户显然处于单独的DbContext中的问题。为此,我将声明一个简化的User实体,以便在应用程序DbContext定义中引用,该定义仅包含与典型用法相关的属性。

给定一个名为Users的表,其中包含凭据、密码/令牌等的引用,但也可能有特定于应用程序的详细信息:

AppIdentityContext看到一个IdentityUser,它公开了验证和授权用户所需的用户ID、凭据等。

AppContext看到一个用户,它公开用户ID、电子邮件以及附加或链接到用户表的任何应用程序详细信息,但不公开身份验证/授权详细信息。

这两个实体都链接到同一个表,但服务于不同的关注点。

有这样的代码是没有意义的:

var order = _context.Orders.Where(x => x.OrderId == orderId).Select(x => new 
{
x.OrderId,
x.OrderNumber,
x.CreatedBy.UserId,
x.CreatedBy.Credential.PasswordHash // <- Not an application concern.
}).Single();

无论是开发人员有意还是无意,用户的应用程序问题都不应具有暴露或篡改与身份验证或授权相关的详细信息的潜力。如果代码正在执行类似于序列化实体图的操作,那么这一点将尤为重要。

如果我想在应用程序中支持更具管理性的东西,或者支持一个单独的应用程序来管理用户,那将是它自己的DbContext定义,对应用程序和Auth关注的字段都有更高的公开度。此管理上下文&功能将暴露应用程序和身份验证/授权的详细信息:

AppAdminContext看到一个FullAppUser,它公开用户ID、电子邮件、所有应用程序详细信息以及身份验证/授权详细信息。可以创建/编辑用户、调整角色、重置密码以及管理应用程序特定详细信息的功能将使用此DbContext和完整用户来管理用户的各个方面。

对于一个简单的应用程序来说,这似乎有些过头了,但IMO证明关注点分离是一个很好的做法。

最新更新