我正在尝试将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/