C# 实体框架核心5.0-映射表中带有附加字段的多对多
我正在使用EF Core 5.0,并尝试创建多对多关系:C# 实体框架核心5.0-映射表中带有附加字段的多对多,c#,entity-framework-core,many-to-many,C#,Entity Framework Core,Many To Many,我正在使用EF Core 5.0,并尝试创建多对多关系: public class User { public int Id { get; set; } public ICollection<UserItem> UserItems { get; set; } } public class Item { public int Id { get; set; } public ICollection<UserItem> UserItems {
public class User
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
}
public class Item
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
}
public class UserItem
{
public int Id { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public int ItemId { get; set; }
public Item Item { get; set; }
public int Quantity { get; set; }
}
公共类用户
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
}
公共类项目
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
}
公共类用户项
{
公共int Id{get;set;}
public int UserId{get;set;}
公共用户{get;set;}
公共int ItemId{get;set;}
公共项项{get;set;}
公共整数数量{get;set;}
}
如您所见,
UserItem
类有一个名为Quantity
的附加属性,我想知道这是否是正确的方法,以及如何将所有这些映射到DBContext
类中?一切都很好,也许您需要添加到DBContext中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserItem>(entity =>
{
entity.HasOne(d => d.User)
.WithMany(p => p.UserItems)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
entity.HasOne(d => d.Item)
.WithMany(p => p.UserItems)
.HasForeignKey(d => d.ItemId)
});
OnModelCreatingPartial(modelBuilder);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity(Entity=>
{
entity.HasOne(d=>d.User)
.WithMany(p=>p.UserItems)
.HasForeignKey(d=>d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
entity.HasOne(d=>d.Item)
.WithMany(p=>p.UserItems)
.HasForeignKey(d=>d.ItemId)
});
OnModelCreatingPartial(modelBuilder);
}
但如果您使用Net5,则可以添加项目列表:
public class User
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
public ICollection<Items> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
public ICollection<Users> Users { get; set; }
}
公共类用户
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
公共ICollection项{get;set;}
}
公共类项目
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
公共ICollection用户{get;set;}
}
一切正常,也许您需要添加到dbContext中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserItem>(entity =>
{
entity.HasOne(d => d.User)
.WithMany(p => p.UserItems)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
entity.HasOne(d => d.Item)
.WithMany(p => p.UserItems)
.HasForeignKey(d => d.ItemId)
});
OnModelCreatingPartial(modelBuilder);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity(Entity=>
{
entity.HasOne(d=>d.User)
.WithMany(p=>p.UserItems)
.HasForeignKey(d=>d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
entity.HasOne(d=>d.Item)
.WithMany(p=>p.UserItems)
.HasForeignKey(d=>d.ItemId)
});
OnModelCreatingPartial(modelBuilder);
}
但如果您使用Net5,则可以添加项目列表:
public class User
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
public ICollection<Items> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public ICollection<UserItem> UserItems { get; set; }
public ICollection<Users> Users { get; set; }
}
公共类用户
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
公共ICollection项{get;set;}
}
公共类项目
{
公共int Id{get;set;}
公共ICollection用户项{get;set;}
公共ICollection用户{get;set;}
}
是的,这是正确的!
但是我建议从UserItem
中删除Id属性,并使用-
modelBuilder.Entity<UserItem>()
.HasKey(userItem => new { userItem.UserId, userItem.ItemId });
如果要在删除用户时级联UserItem
,但在UserItem
仍引用所述项目时限制删除该项目,请添加-
modelBuilder.Entity<UserItem>()
.HasOne(userItem => userItem.User)
.WithMany(user => user.UserItems)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<UserItem>()
.HasOne(userItem => userItem.Item)
.WithMany(item => item .UserItems)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasOne(userItem=>userItem.Item)
.WithMany(item=>item.UserItems)
.OnDelete(DeleteBehavior.Restrict);
如果用户和项目被UserItem
引用,则要限制对它们的删除。请注意,您至少需要其中一个,否则在添加迁移时会出现异常,因为您有多个级联路径用于UserItem
是的,这是正确的!
但是我建议从UserItem
中删除Id属性,并使用-
modelBuilder.Entity<UserItem>()
.HasKey(userItem => new { userItem.UserId, userItem.ItemId });
如果要在删除用户时级联UserItem
,但在UserItem
仍引用所述项目时限制删除该项目,请添加-
modelBuilder.Entity<UserItem>()
.HasOne(userItem => userItem.User)
.WithMany(user => user.UserItems)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<UserItem>()
.HasOne(userItem => userItem.Item)
.WithMany(item => item .UserItems)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasOne(userItem=>userItem.Item)
.WithMany(item=>item.UserItems)
.OnDelete(DeleteBehavior.Restrict);
如果用户和项目被
UserItem
引用,则要限制对它们的删除。请注意,您将至少需要其中一个,否则在添加迁移时会出现异常,因为您有多个级联路径用于UserItem
谢谢。我有一个关于删除行为的问题:-如果删除了UserItem,则不应删除任何其他内容。-如果删除了用户,则应删除关联的UserItems。-如果删除了项目,则应删除关联的UserItems^如何设置?您可以尝试.OnDelete(DeleteBehavior.ClientCascade);相反,但我不建议你这么做。在任何情况下,它都不能正常工作,并可能导致事故。更好的方法是手动将所有项目包括在删除操作中。OnDelete(DeleteBehavior.ClientSetNull)-是最安全的选项。谢谢。我有一个关于删除行为的问题:-如果删除了UserItem,则不应删除任何其他内容。-如果删除了用户,则应删除关联的UserItems。-如果删除了项目,则应删除关联的UserItems^如何设置?您可以尝试.OnDelete(DeleteBehavior.ClientCascade);相反,但我不建议你这么做。在任何情况下,它都不能正常工作,并可能导致事故。更好的方法是手动将所有项目包括在删除操作中。OnDelete(DeleteBehavior.ClientSetNull)-是最安全的选项。这就是我需要的一切!但是有一个问题,我能不能将新的复合键映射到UserItem类中的ID字段?@Azhari我认为这是不可能的,因为复合键由两个整数组成