【发布时间】:2021-04-21 17:23:33
【问题描述】:
我有一个Channel 域模型:
public class Channel
{
public string Id {get; set;}
public List<ChannelUser> ChannelUsers {get; set;}
}
还有一个ChannelUser 类如下(我在表上有额外的元数据,为简洁起见,在此处删除,这就是为什么我使用特定类来表示多对多关系)。
public class ChannelUser
{
public string ChannelId {get; set;}
public string UserId {get; set;}
}
ChannelUser 的主键是 (ChannelId, UserId)。
这些 ChannelUser 中的一个(并且只有一个)可以是 Channel 的所有者。 理论上,一个用户可以是许多频道的所有者(但显然,一个 ChannelUser 只能是它所关联的频道的所有者)。
我想在数据库级别强制执行这一点,而不是在 ChannelUser 上使用“IsOwner”属性并使用业务逻辑来确保每个通道只设置一次标志。我还想强制 ChannelOwner 是 ChannelUser 之一,因此不希望直接来自 Channel > User 的关系,而是将其保留为 Channel > ChannelUser。
因此我将Channel类更新如下:
public class Channel
{
public string Id {get; set;}
public List<ChannelUser> {get; set;}
public ChannelUser Owner {get; set;}
}
并添加了以下流畅的API表达式:
modelBuilder.Entity<ChannelUser>().HasKey(cu => new { cu.ChannelId, cu.UserId });
modelBuilder.Entity<ChannelUser>().HasOne<Channel>(x => x.Channel).WithMany(x => x.ChannelUsers)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<ChannelUser>().HasOne<User>(x => x.User).WithMany(x => x.UserChannels)
.OnDelete(DeleteBehavior.NoAction);
添加迁移时会导致:
Both relationships between 'ChannelUser.Channel' and 'Channel.ChannelUsers' and between 'ChannelUser' and 'Channel.Owner' could use {'ChannelId'} as the foreign key. To resolve this configure the foreign key properties explicitly on at least one of the relationships.
我理解,但我认为这是我们想要的。因为 ChannelUser.ChannelId 应该始终是两个关系的相同 Channel.Id。
请任何人都可以建议我如何构建这种关系或仍然强制执行表之间的many to many 和one to one 关系的替代方法?
【问题讨论】:
-
用简单的英语陈述思考。一个频道有多个用户。一个频道只有一个所有者。用户可以拥有多个频道,但可以是任何单个频道的所有者。因此,三个表 Channel、User 和 ChannelUser 之间的关系就像通道和用户之间的多对多以及所有者关系之间的一对一一样。在您的 Channel 类中,您将 Owner 引用为 ChannelUser 而不是 User 类,这有点循环引用。此外,您应该拥有 User 和 Channel 而不是 ChannelUser 的列表,因为它只是中间类,除非您有额外的元数据。
-
感谢您的评论。我更新了我的问题以澄清:用户可以是许多频道的所有者(但 ChannelUser 只能是一个频道的所有者,由 ChannelId 确定)。我确实有关于这种关系的额外元数据,为了简洁起见,我只是省略了。谢谢,
-
我将创建关系 Channel > User 以按照您的建议表达主要所有者。如果你想写作为答案,我会接受。
-
深入研究,这是可能的,但您的数据结构可能需要稍作更改以适应约束。
标签: entity-framework entity-framework-core