簡體   English   中英

在Entity Framework核心中更新和管理多對多關系

[英]Updating and managing many-to-many relation in Entity Framework core

我正在構建一個ASP.NET核心REST服務器。 我需要知道如何正確更新實體之間的多對多關系-我想通過Entity Framework核心添加,刪除和更新鏈接表中的某些記錄。

我的代碼:

用戶模型

public class User
{
    [Key]
    public int IDUser { get; set; }
    [Required]
    public string Forename { get; set; }
    [Required]
    public string Name { get; set; }
    public string AvatarPath { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
    public string Password { get; set; }
    public User CreatedBy { get; set; }
    public DateTime CreatedAt { get; set; }

    public List<UserPermission> UsersPermissions { get; set; }
}

權限模型

public class Permission
{
    [Key]
    public int IDPermission { get; set; }
    public string Name { get; set; }

    [Required]
    public int IDMachine { get; set; }
    public Machine Machine { get; set; }

    public List<UserPermission> UsersPermissions { get; set; }
}

UserPermission模型-鏈接表

public class UserPermission
{
    [Key]
    public int IDUserPermission { get; set; }

    public int IDUser { get; set; }
    public int IDPermission { get; set; }
    public User User { get; set; }
    public Permission Permission { get; set; }
}

DbContext

public class DBContext : DbContext
{
    public DBContext(DbContextOptions<DBContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
           .HasIndex(u => u.Email)
           .IsUnique();

        modelBuilder.Entity<UserPermission>()
            .HasIndex(bp => new { bp.IDPermission, bp.IDUser })
            .IsUnique();

        modelBuilder.Entity<UserPermission>()
            .HasOne(up => up.User)
            .WithMany(u => u.UsersPermissions)
            .HasForeignKey(up => up.IDUser);

        modelBuilder.Entity<UserPermission>()
            .HasOne(up => up.Permission)
            .WithMany(p => p.UsersPermissions)
            .HasForeignKey(up => up.IDPermission);

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Machine> Machines { get; set; }
    public DbSet<Permission> Permissions { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UserPermission> UsersPermissions { get; set; }
}

PermissionsController-HttpGet

[HttpGet("{id}", Name = "GetPermissionByID")]
public async Task<IActionResult> GetPermissionByID(Int32 id)
{
    try
    {
        var permission = await _context.Permissions.Include(p => p.UsersPermissions).FirstOrDefaultAsync(s => s.IDPermission == id);

        if (permission == null)
        {
            return NotFound();
        }
        else
        {
            return new ObjectResult(permission);
        }
    }
    catch (Exception ex)
    {
        Helpers.ExceptionLogger.LogException(ex);
        return StatusCode(500);
    }

}

PermissionController-HttpPut

[HttpPut("{id}")]
public async Task<IActionResult> UpdatePermission(int id, [FromBody]Permission permission)
{
    if (permission == null || permission.IDPermission != id)
    {
        return BadRequest();
    }

    try
    {
        var permissionToupdate = await _context.Permissions.Include(p => p.UsersPermissions).AsNoTracking().FirstOrDefaultAsync(u => u.IDPermission == id);
        if (permissionToupdate == null)
        {
            return NotFound();
        }

        permissionToupdate.IDMachine = permission.IDMachine;
        permissionToupdate.IDPermission = permission.IDPermission;
        permissionToupdate.Machine = permission.Machine;
        permissionToupdate.Name = permission.Name;
        permissionToupdate.UsersPermissions = permission.UsersPermissions; // it doesn't actually work

        _context.Permissions.Update(permissionToupdate);
        await _context.SaveChangesAsync();
        return new NoContentResult();
    }
    catch (Exception ex)
    {
        Helpers.ExceptionLogger.LogException(ex);
        return StatusCode(500);
    }
}

當我調用HttpPut操作並嘗試更新該行中的UsersPermissions表格時, permissionToupdate.UsersPermissions = permission.UsersPermissions; ;。 EF不會對SQL Server生成正確的查詢。 我希望能夠通過修改UsersPermissions導航屬性來添加,刪除和更新該鏈接表中的某些記錄。 看來我做錯了什么或不知道如何實現。 有人可以指導我我有什么選擇嗎? 在我的情況下,如何添加,刪除和更新鏈接表?

我不知道有什么好的做法說,但我只是想知道:你會如何管理鏈接TABEL UsersPermissions實體之間UserPermissions

  • 1)通過創建單獨的控制器UsersPermissionsController專門到那個鏈接表格UsersPermissions ,以便添加,刪除,更新記錄?
  • 2)通過更新Permission實體中的導航屬性Permission.UsersPermissions來添加,刪除,更新記錄?

您不能只將一個列表替換為另一個。 由於EF Core使用更改跟蹤,因此您似乎要對初始列表中的所有內容進行刪除,然后對所有內容添加新列表。 然后,由於實際上確實存在一些被“添加”的實體,因此EF最終會出現沖突的實體狀態。

總而言之,您需要有選擇地刪除已刪除的項目,並添加新的項目,而無需保留現有關系。

permissionToUpdate.UserPermissions
    .Except(permission.UserPermissions)
    .ToList()
    .ForEach(x => permissionToUpdate.UserPermissions.Remove(x));

permission.UserPermissions
    .Except(permissionToUpdate.UserPermissions)
    .ToList()
    .ForEach(x => permissionToUpdate.UserPermissions.Add(x));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM