簡體   English   中英

實體框架將用戶添加到角色

[英]Entity Framework Add User to Role

我剛才問了一個問題,在這里回答了

基本上我有兩個需要的類:

public class User : IUser
{
    public string Id { get; set; }

    // Stripped for brevity

    public IList<Role> Roles { get; set; }

    public User()
    {
        this.Id = Guid.NewGuid().ToString();
    }
}

public class Role : IRole
{
    public string Id { get; set; }
    public string Name { get; set; }

    public Role()
    {
        this.Id = Guid.NewGuid().ToString();
    }
}

在我的DbContext中,我有以下聲明:

modelBuilder.Entity<User>()
    .HasMany(m => m.Roles)
    .WithMany()
    .Map(m => { 
        m.MapLeftKey("UserId");
        m.MapRightKey("RoleId"); 
        m.ToTable("UserRoles"); 
    });

一切都完美。 現在,我想將用戶添加到特定角色,因此我按照服務/存儲庫/工作單元設計模式創建了一個服務,如下所示:

public class UserRoleService : Service<UserRole>
{
    public UserRoleService(IUnitOfWork unitOfWork)
        : base(unitOfWork)
    {

    }

    public async Task<IList<UserRole>> GetAllAsync(string userId, params string[] includes)
    {
        return await this.Repository.GetAll(includes).Where(m => m.UserId.Equals(userId, StringComparison.OrdinalIgnoreCase)).ToListAsync();
    }

    public async Task CreateAsync(UserRole model)
    {
        var isInRole = await IsInRole(model.UserId, model.RoleId);

        if (isInRole)
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.UserInRole, new object[] { model.RoleId }));

        this.Repository.Create(model);
    }

    public async Task RemoveAsync(UserRole model)
    {
        var isInRole = await IsInRole(model.UserId, model.RoleId);

        if (!isInRole)
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.UserNotInRole, new object[] { model.RoleId }));

        this.Repository.Remove(model);
    }

    public async Task<bool> IsInRole(string userId, string roleId)
    {
        if (string.IsNullOrEmpty(userId))
            throw new ArgumentNullException("userId");

        if (string.IsNullOrEmpty(userId))
            throw new ArgumentNullException("roleId");

        var roles = await this.GetAllAsync(userId);
        var match = roles.Where(m => m.RoleId.Equals(roleId, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();

        return (match == null);
    }
}

繼承的服務類如下所示:

public class Service<T> where T : class
{
    private readonly IRepository<T> repository;

    protected IRepository<T> Repository
    {
        get { return this.repository; }
    }

    public Service(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new ArgumentNullException("unitOfWork");

        this.repository = unitOfWork.GetRepository<T>();
    }
}

現在,由於我的DbContext沒有針對UserRolesDbSet ,因此我添加了一個。 然后,我抱怨新表沒有設置主鍵,因此我添加了一個。 所以現在我的DbContext看起來像這樣:

public class DatabaseContext : DbContext
{
    // Removed for brevity
    public DbSet<Role> Roles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }

    static DatabaseContext()
    {
        //Database.SetInitializer<IdentityContext>(null); // Exsting database, do nothing (Comment out to create database)
    }

    public DatabaseContext()
        : base("DefaultConnection")
    {
        base.Configuration.LazyLoadingEnabled = false; // Disable Lazy Loading
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); // Remove Cascading Delete

        // Removed from brevity
        modelBuilder.Entity<UserRole>().HasKey(m => new { m.UserId, m.RoleId });
        modelBuilder.Entity<User>()
            .HasMany(m => m.Roles)
            .WithMany()
            .Map(m => { 
                m.MapLeftKey("UserId");
                m.MapRightKey("RoleId"); 
                m.ToTable("UserRoles"); 
            });
    }
}

我現在遇到的問題是,我的代碼為UserRole創建了兩個表,分別稱為UserRolesUserRoles1 有人可以告訴我如何只使用一張桌子嗎?

如果UserRole表示純映射 (即,它僅包含UserId和RoleId,並且不包含其他屬性),則實際上不需要UserRole對象。 在您的DbContext中定義關系就足夠了(您已經完成了)。 為了將特定角色與特定用戶相關聯,您可以簡單地執行以下操作:

user.Roles.Add(role);

...並提交DbSet

實體框架足夠聰明,可以為您維護多對多映射表,而無需實際擁有表示映射本身的實體。

注意:您要添加的角色對象必須是數據庫上下文中的實體。 如果嘗試創建角色實體然后進行分配,則EF將嘗試插入(可能由於主鍵沖突而失敗)。

暫無
暫無

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

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