C# 实体框架核心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 {

我正在使用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 { 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我认为这是不可能的,因为复合键由两个整数组成