我有一个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)。
这些ChannelUsers中的一个(且只有一个)可以是通道的所有者。从理论上讲,用户可以是多个频道的所有者(但显然,ChannelUser只能是与其关联的频道的所有者)。
我想在数据库级别强制执行,而不是在ChannelUser上使用"IsOwner“属性,并使用业务逻辑来确保每个通道只设置一次该标志。我还想确保ChannelOwner是ChannelUsers中的一个,因此不希望直接从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关系?

发布于 2021-04-21 17:23:34
这不是理想的方法,但可以做到,看看这个ER图:

理想的方法是拥有适当的实体映射,如下所示:
用户类:
public class User
{
public string Id {get; set;}
public virtual List<Channel> Channels {get; set;}
// Other properties....
}通道类:
public class Channel
{
public string Id {get; set;}
public List<User> Users {get; set;}
public User Owner {get; set;}
public string? OwnerId { get; set; }
public User Owner { get; set; }
}要加入这两个类的ChannelUser类:
public class ChannelUser
{
public string Id {get; set;}
public string ChannelId {get; set;}
public string UserId {get; set;}
}映射:
modelBuilder.Entity<User>()
.HasMany<Channel>(user => user.channels)
.WithMany(channel => channel.users)
.Map(cu =>
{
cu.MapLeftKey("UserId");
cu.MapRightKey("ChannelId");
cu.ToTable("ChannelUser");
});
// configure one-to-many relationship for ownership
modelBuilder.Entity<Channel>()
.HasRequired<User>(c => c.User)
.WithMany(u => u.ChannelId )
.HasForeignKey<int>(c => c.UserId);在标准化后,在控制器代码中检查用户是否存在的责任应该相当容易,或者我们可以使用DB过程,触发器来创建约束,检查给定的所有者ID是否确实在给定通道的ChannelUser表中。
https://stackoverflow.com/questions/67191506
复制相似问题