2014-11-05 2 views
1

У меня проблема. У меня есть Пользователь, который может иметь много ролей, но Роли являются глобальными, поэтому я создал структуру таблицы следующим образом:Entity Framework и роли

CREATE TABLE [dbo].[Users](
    [Id] [nvarchar](128) NOT NULL, 
    [UserName] [nvarchar](max) NULL, 
    [Email] [nvarchar](max) NULL, 
    [DateCreated] [datetime] NOT NULL, 
    [DateModified] [datetime] NULL, 
    [LastLoginDate] [datetime] NOT NULL, 
    [PasswordHash] [nvarchar](max) NULL, 
CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED 

CREATE TABLE [dbo].[UserRoles](
    [UserId] [nvarchar](128) NOT NULL, 
    [RoleId] [nvarchar](128) NOT NULL, 
CONSTRAINT [PK_dbo.UserRoles] PRIMARY KEY CLUSTERED 
(
    [UserId] ASC, 
    [RoleId] ASC 
) 

CREATE TABLE [dbo].[Roles](
    [Id] [nvarchar](128) NOT NULL, 
    [Name] [nvarchar](max) NULL, 
CONSTRAINT [PK_dbo.Roles] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
) 

UserRoles таблица foriegn клавиши настройки как для Роли и Пользователи таблица на соответствующем Id столбцы.

В моем коде, у меня есть это:

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

    // Stripped for brevity 

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

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

public class UserRole 
{ 
    public string RoleId { get; set; } 
    public string UserId { get; set; } 
} 

public class Role : IRole 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public IList<UserRole> Users { get; set; } 

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

EntityFramework прекрасно с этим классом и с моим отображением следующим образом:

modelBuilder.Entity<UserRole>().HasKey(m => new { m.UserId, m.RoleId }); 

Все для отображения работы. Теперь, что бы я хотел, для Пользователь класс должен иметь список Роли и не UserRoles.

Итак, я хотел бы, чтобы выглядеть следующим образом:

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(); 
    } 
} 

Я уверен, что вы можете увидеть здесь проблемы. Может кто-нибудь подумать о решении, где моя структура таблицы остается прежней, но я могу получить доступ к Ролям вместо UserRoles?

Извините, если мои объяснения не очень хорошие.

ответ

1

Я думаю, что вы после этого что-то вроде этого ...

В DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>() 
       .HasMany(x => x.roles) 
       .WithMany(x => x.users) 
       .Map(x => 
       { 
        x.MapLeftKey("userId"); 
        x.MapRightKey("roleId"); 
        x.ToTable("UserRole"); 
       }); 
} 

Теперь у вас есть.

class User 
{ 
    ICollection<Role> roles {get; set;} 
} 

и

class Role 
{ 
    ICollection<User> users {get; set;} 
} 
+0

Мне не нужно было создавать другую таблицу здесь, должно быть что-то, что я могу сделать, чтобы получить модель для доступа к роли, а не к UserRole. – r3plica

+0

Этот ответ использует только те три таблицы, которые у вас уже есть. Фактически с этим в вашем dbContext будут только пользователи и роли, таблица UserRole существует только в db, чтобы обеспечить сопоставление между ними. –

0

Я думаю, что ответ на это просто добавление роли в класса UserRole так:

public class UserRole 
{ 
    public string RoleId { get; set; } 
    public string UserId { get; set; } 

    public Role Role { get; set; } 
} 

Это тогда даст мне доступ до Роль.

+0

Нет необходимости в классе UserRole. –

+0

Хорошо, теперь вы обновили свой ответ. Я вижу, что вы имеете в виду. Если я хочу добавить пользователя к роли, не нужен ли мне этот класс UserRole? – r3plica

+1

Нет, просто добавьте пользователя в коллекцию пользователей в классе Role или добавьте роль в коллекцию ролей в классе User, сохраните изменения, а EF добавит строку в таблицу UserRole и обновит коллекции, чтобы они были оба правильные. –

0

Какой подход вы следуете? кода/модели/базы данных. Я думаю, что вам не нужен класс UserRole.having в роли «Роль и пользователь», и EntityFramework достаточно умен, чтобы понять, что у вас есть много-много RelationShip, поэтому он создаст соедините таблицу внутри базы данных, но выведете ее в код следующим образом: User.Roles.Add (Role arole) и Role.Users.Add (User auser).

Надеемся, что эта помощь

Редактировать: OOOps. тот же ответ был дан мне передо мной .. я этого не видел.