我正在学习 Asp.net 核心和实体框架核心,我创建了一个基本的Web应用程序,其中包含具有代码优先方法的数据库。我的应用程序有一个上下文(AppContext(,为了使用Identity,我定义了一个新的上下文(IdentityContext(,它使用相同的数据库。 我想将每个标识的用户(来自 IdentityContext 的 AppUser(与一个员工(来自 AppContext(相关联,但是当我尝试这样做时,EF Core 会为其创建一个新表。
public class AppUser : IdentityUser
{
public Employee Employee { get; set; }
}
public class Employee
{
public long Id { get; set; }
public string AspNetUserId { get; set; }
public AppUser AppUser { get; set; }
}
应用上下文
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>(employee =>
{
employee.HasIndex(e => e.AspNetUserId);
employee
.HasOne(e => e.AppUser)
.WithOne(au => au.Employee)
.HasForeignKey<Employee>(e=>e.AspNetUserId);
});
}
我对此有很多疑问:
- 我认为有两个单独的上下文是可以的,每个上下文只有一个关注点。可以吗?还是应该将我的应用程序上下文复制粘贴到身份上下文上?
- 如何告诉我的 AppContext 没有为 AppUser 创建新表,并使用 IdentityContext 创建的表?
- 还有其他选择吗?
任何建议或参考将不胜感激。
谢谢。
单独的上下文是可以的,每个上下文都有一个 一个问题。可以吗?还是我应该将我的应用程序上下文复制粘贴到 身份背景?
完全没问题。问题是你想把他们分开,但又不让他们有自己的顾虑。
您当前正在告诉您的 IdentityContext 它应该同时具有 AppUser 和 Employee,并且它们之间存在关系。然后上下文将照顾它们,除非您明确告诉它不要这样做。但是现在你明确地告诉它。
它几乎可以总结为这个简单的规则:分离的上下文 ->分离的数据。
如何告诉我的应用程序上下文不会为 创建新表 AppUser,并使用由 IdentityContext 创建的表?
你真的不应该。不要指望实体框架处理上下文之间的关系。它几乎不会。如果您的实体具有连接,则它们属于同一上下文。您可以将其视为不同的数据库。在两个不同的数据库之间进行查询并不是那么顺利。
但是,您仍然可以通过告诉配置忽略引用的实体来分隔它们,如下所示:
modelBuilder.Entity<AppUser>().Ignore(e => e.Employee);
但是,这可能只会令人困惑,因为除非您自己做,否则这些实体不会被跟踪或映射。因此,我建议要么坚持使用 Id 作为引用/外键,让他们过自己的生活,要么将它们结合起来并执行您当前的计划。坚持一个上下文是我建议的,如果你是游戏新手。
还有其他选择吗?
我喜欢为标识分离一个上下文的想法,因为某些逻辑可能与 UI 层相关,并且实际上很少需要对用户上其他实体的任何引用。它确实在迁移等方面需要一些额外的努力,但总而言之,它运行良好。您仍然可以通过一些简洁的泛型方法和接口轻松获取属于用户的相关实体。
但是,如果我的实体少于 15-20 个,即使我也不会这样做。只是不值得。在这么小的项目中,好处还是太少了。