2014-11-05 48 views
0

我问了一个问题前面这是answered here实体框架添加用户到角色

基本上我有需要有2类:

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没有一个DbSet的UserRole它抱怨,所以我加了一个。然后我得到了一个抱怨,新表没有设置主键,所以我添加了一个。所以,现在我的的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称为的UserRoleUserRoles1。 有人能告诉我如何让它只使用一个表?

+0

你使用过会员吗? – 2014-11-05 22:25:57

+0

您的用户拥有角色,但您的角色没有用户。因此,将角色添加到角色在您的上下文中并不明显。构建您的语言以匹配您的数据模型,或者构建您的数据模型以符合您的语言。 – 2014-11-05 22:31:50

回答

3

如果UserRole代表纯映射(即,它仅包含UserId和RoleId,并且没有其他属性),那么实际上并不需要UserRole对象。在你的DbContext中定义关系就足够了(你已经完成了)。为了一个特定的角色与特定用户关联起来,你可以简单地做:

user.Roles.Add(role); 

...并提交DbSet

实体框架是足够聪明的保持许多一对多映射表因为你实际上没有代表映射本身的实体。

注意:您尝试添加的角色对象需要来自数据库上下文的实体。如果您尝试创建角色实体然后分配,EF将尝试插入(并可能由于主键违例而失败)。

+0

伟大:)我目前遇到的唯一问题是,它似乎并没有保存,但我会为此发布另一篇文章。 – r3plica 2014-11-06 14:56:24

+0

想通了,不需要另一个问题:) – r3plica 2014-11-06 15:37:36