entity-framework-core - EFCore将2个实体映射到同一张表

标签 entity-framework-core

我正在尝试将DDD与EFCore结合使用,并且努力寻找一种方法来将表示同一实体的来自不同上下文的2个POCO映射到同一张表。

我在UserContext中有一个User类,其中包含为我的应用程序创建新用户所需的所有属性。
而且我在OrderContext中有一个User类,在该类中我仅具有Id和Email属性,因为这是OrderContext工作所需的全部。

所以我有这样的事情:

        modelBuilder.Entity<Domain.UserContext.User>(u =>
        {
            u.ToTable("User").HasKey(e => e.Id);
            u.OwnsOne(e => e.Name);
            u.OwnsOne(b => b.HomeAddress);
        });

        modelBuilder.Entity<Domain.OrderContext.User>(u =>
        {
            u.ToTable("User").HasKey(e => e.Id);
        });

        modelBuilder.Entity<Domain.OrderContext.Order>(p =>
        {
            p.ToTable("Order").HasKey(b => b.Id);
            p.HasOne(x => x.User); // this is OrderContext.User
        });


我似乎找不到一种将两个User类映射到同一张表的方法。有办法吗?

Edit1:这两个上下文都是有界上下文DDD的概念,而不是DbContext。
我只需要将两个类映射为同一张表。 Add-Migration命令返回一条消息,告诉我它无法将“ OrderContext.User”映射到表“ User”,因为它已映射到“ UserContext.User”。

最佳答案

问题的主要原因是,EF Core无法弄清楚如何将相同的表用于2个不同的实体。映射中缺少数据,一旦填写,它就会按预期工作。

首先,您需要定义它们之间的关系。与相同的PK共享同一表并没有在服务器端定义外键,但是两个实体之间仍然存在一对一的内在关系,并且使用PK作为FK。定义关系后,您将看到它起作用,并且两个实体都映射到同一张表。 (就像拥有实体如何映射到同一表一样)。不过,这可能并不代表您的情况已经结束。由于从EF角度来看,它们仍然是2个不同的实体,除了Id(或PK属性)外,它们将具有自己的列来存储数据。但是,如果您有在两种情况下都通用的列(如您的方案中的Email),该怎么办。在这种情况下,您还需要为这些其他列提供映射。如果您将它们明确映射到同一列,则它们将开始共享数据库中的列。总体来说,代码看起来像这样。

namespace UserContext
{
    public class User
    {
        public int Id { get; set; }
        public string Email { get; set; }
        // Other properties
    }
}

namespace OrderContext
{
    public class User
    {
        public int Id { get; set; }
        public string Email { get; set; }
    }
}

// In OnModelCreating method
modelBuilder.Entity<UserContext.User>(u =>
{
    u.ToTable("User");
    u.Property(e => e.Email).HasColumnName("Email");
    // Configuration for other properties
});

modelBuilder.Entity<OrderContext.User>(u =>
{
    u.ToTable("User");
    u.Property(e => e.Email).HasColumnName("Email");
    u.HasOne<UserContext.User>().WithOne().HasForeignKey<OrderContext.User>(e => e.Id);
});


上面的代码创建带有共享列的单个表,并且应该可以正常工作。如果需要,可以通过以下相同配置在同一表中添加更多实体。在这里,我使用User中的UserContext作为主要方面,但您可以使用任何方面。对我来说,主要原因是UserContext.User是添加新用户时要添加的实体。共享表的实体也不必是子集。但是会有一些不共享的其他属性列。

关于entity-framework-core - EFCore将2个实体映射到同一张表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49986756/

相关文章:

c# - EF Core Update 会更新所有列,即使只有一列已更改

c# - Entity Framework Core 中的自引用多对多关系

c# - 如何在不选择新模型的情况下包含导航属性?

asp.net-core - EF Core 迁移错误 : "Unable to create an object of type ' ApplicationContext'"

c# - 使用 EF Core 获取存储过程的输出参数值?

entity-framework-core - EF Core 多个左连接

c# - EF Core 包含多层次问题

visual-studio - 指定的 LocalDB 实例名称无效 : Able to create migrations but not run them

c# - Entity Framework - 如何正确配置一对多关系导航属性

c# - 如何检测 Entity Framework Core 2.x 中特定实体的属性更改?