2
votes

I am using EF 4 Feature CTP 4.

I have the following database schema:

[Users] 1-M [UserRoles] M-1 [Roles]

I have a User and Role class (both POCOs).

When I try to associate an existing role to a user, a new record is getting inserted in the Roles table, instead of only inserting a new record in UserRoles.

So say I have User 1 and want to Associate with Role 2. When I try to save, I end up with a new record in Roles named "Role 2" with a record in UserRoles to the newly created Role. From the code below I was expecting only a new record in UserRoles with the mapping between User and Role.

Here is my POCO classes, mapping and test.

POCO Classes:

public class User {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public byte[] DataVersion { get; set; }

        private List<Role> roles = new List<Role>();
        public virtual IList<Role> Roles {
            get {
                return roles;
            }
        }   
    }

public class Role {
        public int Id { get; set; }
        public string Name { get; set; }

        public List<User> Users { get; set; }
    }

Mapping:

public class UserConfiguration : EntityConfiguration<Domain.User> {
        public UserConfiguration() {
            this.MapSingleType(user => new {
                UserId = user.Id,
                FirstName = user.FirstName,
                LastName = user.LastName,
                DataVersion = user.DataVersion
            });

            this.Property(u => u.DataVersion).IsConcurrencyToken().HasStoreType("timestamp").StoreGeneratedPattern = StoreGeneratedPattern.Computed;

            //Users <--> Roles
            this.HasMany(u => u.Roles).WithMany(r => r.Users)
                .Map("UserRoles", (u, r) => new {
                    UserId = u.Id,
                    RoleId = r.Id
                });  
        }
   }

public class RoleConfiguration : EntityConfiguration<Domain.Role> {
        public RoleConfiguration() {
            this.MapSingleType(role => new {
                RoleId = role.Id,
                RoleName = role.Name
            });

        }
    }

Test:

public void AssignRoleTest() {
            var userId = 1;
            User user;

            var userRepo = new UsersRepository();
            user = userRepo.GetUser(userId);

            var roleRepo = new RolesRepository();

            var roleId = 2;
            var role = roleRepo.GetRole(roleId);

            user.Roles.Add(role);

            userRepo.SaveUser(user);

     }

Code for Repository Save:

public void SaveUser(User user) {
        if (user.Id > 0) {
            dbContext.Users.Attach(user);
            dbContext.MarkAsModified(user);
        }
        else {
            dbContext.Users.Add(user);
        }
1

1 Answers

0
votes

Try to use context.DetectChanges() in your SaveUser method. It should work because you are using same context for both loading and saving entity graph.