I'm currently creating an application with EntityFramework and aspnet membership tables combined.
To create the aspnet membership tables dynamically, I followed this tutorial: http://imar.spaanjaars.com/563/using-entity-framework-code-first-and-aspnet-membership-together
My problem is the aspnet_UsersInRoles table. To map the table I modified OnModelCreating and add the ff code:
modelBuilder.Entity<AspnetUser>()
.HasMany(u => u.AspnetRoles)
.WithMany(r => r.AspnetUsers)
.Map(m =>
{
m.ToTable("aspnet_UsersInRoles");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
It created successfully the aspnet_UsersInRoles table, but my problem is that I don't have a class/entity for this and I'm unable to initialize value when I override the Seed method.
Creating an entity aspnet_UsersInRoles also doesn't work because the many-to-many relationship between aspnet_Users and aspnet_Roles create a new table.
Any idea on how to do this? Having many to many relationship between aspnet_Users and aspnet_Roles using the table aspnet_UsersInRoles and initializing values in it.
You need to add the Roles to AspnetRoles collection property of the AspnetUser class.
var role = new AspnetRole { Name = "Foo" };
var user = new AspnetUser { Name = "Bar", /*other props*/ };
user.AspnetRoles = new List { role };
context.Users.Add(user);
This will add "Foo" role to the "Bar" user.
Related
I add user and assign role as below code, I user ASP MVC 5 identity and EF code first.
//some Code
var result = manager.Create(insert, applicationUser.PasswordHash);
IdentityResult result2 =null;
if (result.Succeeded)
{
result2 = manager.AddToRole(insert.Id, "User");
}
//Some Code
So i need to show list of user with custom role in view like "User" role. i wrote this code :
ApplicationDbContext myDbContext = new ApplicationDbContext();
var getRoleId = myDbContext.Roles.Where(r => r.Name == "User").Select(m => m.Id).SingleOrDefault();
var fetch = myDbContext.Users.Where(u => u.Roles.Any(r => r.RoleId.ToString() == getRoleId)).ToList();
return View(fetch);
getRoleId value is "4", it is right , but fetch always count equal 0.I try more than 3 4 hours but i can not get result.Where is my wrong ? and what is the solution ?
Thank you.
UPDATE :
I found my problem in add role but i do not know how can fix that !
When adding the users to roles using the above, the users id is added to the UserId column of the UserRoles table, but there was a third column called IdentityUser_Id which was always null.
Out of curiosity I added my user id to that column as well and now the everything works. the application picked up my user role.
My follow up question to this is can I set the IdentityUser_Id automatically? using something similar to the UserManager.AddToRole() which adds the userId to both columns?
Why are you getting getRowId and not pull Users by Role Name? Try Below:
var fetch = myDbContext.Users.Where(u => u.Roles.Any(r => r.Name ==
"User")).ToList();
I have many tables which have foreign key relations. Such as Countries and Cities relationship. When I am deleting the country my application is breaking down because I have foreign key relationship. What I want is if user deletes the country, it should get deleted and set forrign keys to null. Following is my code in OnModelCreating Method:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Player>().HasOptional(r => r.Team)
.WithMany(a => a.Players)
.HasForeignKey(b => new { b.TeamId })
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
Problem here is I have 20 to 25 tables I don't want to do it manually. Is there any code which will automatically set cascade false for entire applciation?
Yes, you can remove the cascade delete for One-to-many and/or Many-to-many conventions in Code First. Just add either or both of these to your OnModelCreating:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
This will disable it, but you can turn cascade delete back on with .WillCascadeOnDelete(true) as needed. See here and here.
EDIT: If your question is about setting FK to null for a collection, you could do this:
Make sure you have a collection of cities on the country.
Expose CountryId as a FK on your City model and make it nullable.
Set them to null and delete the country.
var countryToDelete = context.Country.Include(c => c.Cities).FirstOrDefault(c => c.CountryId == countryIdToDelete;
countryToDelete.Cities.ForEach(c => c.CountryId = null);
context.Country.Remove(countryToDelete);
context.SaveChanges();
I have implemented ASP.Net identity with some custom properties following this article -
http://typecastexception.com/post/2014/06/22/ASPNET-Identity-20-Customizing-Users-and-Roles.aspx
Everything works well, except. I want to get users under specific role (e.g. Get me all the users under Admin role).
I tried following ways to retrieve the users -
var userRole = _roleManager.Roles.SingleOrDefault(m => m.Name == role.Name);
var usersInRole = _userManager.Users.Where(m => m.Roles.Any(r => r.RoleId == userRole.Id));
var usersInRole2 = _userService.GetUsers().Where(u => u.Roles.Any(r => r.RoleId == userRole.Id));
Where _roleManager is of type ApplicationRoleManager : RoleManager<ApplicationRole>. _userManageris of type ApplicationUserManager : UserManager<ApplicationUser, string>.
I am unable to get Roles under user in _userManager and _userService
PS : _userService is service that extends IRepository which queries DbSet<ApplicationUser>.
I can see Roles being properly mapped in table ApplicationUserRoles and I get expected result when I do _userManager.IsInRole(user.Id, "Admin");.
What could've gone wrong with this?
Rahul.
If you are using Entity Framework, it sounds like you are being caught out by lazy loading (since the roles are being added to the database but not when requested from a queryable).
Try something like the following:
_userManager.Users.Include(x => x.Roles).Where(m => m.Roles.Any(r => r.RoleId == userRole.Id));
I figured out where the issue was -
Initially the table ApplicationUserRoles had only primary key definitions, not the foreign key mapping (many to many mapping)..
I added this in OnModelCreating
modelBuilder.Entity<ApplicationUserRole>().HasKey((ApplicationUserRole r) => new { UserId = r.UserId, RoleId = r.RoleId });
//added these definitions
modelBuilder.Entity<ApplicationUser>().HasMany(p => p.Roles).WithRequired().HasForeignKey(p => p.UserId);
modelBuilder.Entity<ApplicationRole>().HasMany(p => p.Users).WithRequired().HasForeignKey(p => p.RoleId);
This completed the relationship and now I can see the Users under Roles and vice versa.
This resulted issue while updating the database, however I just had to do some changes in migration -
The object 'PK_Dbo.ApplicationUserRole' is dependent on column
'UserId'. ALTER TABLE DROP COLUMN UserId failed because one or more
objects access this column.
All I did is, I went to the migration file and moved these lines above DropColumn
DropIndex("dbo.ApplicationUserRole", new[] { "ApplicationUser_Id" });
DropIndex("dbo.ApplicationUserRole", new[] { "ApplicationRole_Id" });
DropPrimaryKey("dbo.ApplicationUserRole");
This solved the update-database exceptions as well.
Rahul
Im new to entity framework. I was trying to map 2 columns of my table(tblEnrollment) to a model(Enrollment). Before that i had changed the name of StudentIdcolumn in tblStudent in the model Student.
EntityTypeConfiguration<Student> studentEntityConfig = modelBuilder.Entity<Student>();
studentEntityConfig.ToTable("tblStudent");
studentEntityConfig.Property(p => p.StuID).HasColumnName("StudentID");
studentEntityConfig.HasKey<int>(s => s.StuID);
EntityTypeConfiguration<Enrollment> enrollmentEntityConfig = modelBuilder.Entity<Enrollment>();
enrollmentEntityConfig.Map(map =>
{
map.Properties(m => new
{
m.EnrollmentId,
m.Grade
});
});
enrollmentEntityConfig.ToTable("tblEnrollment");
Now when I'm trying to call a method to GetAllStudents from db I get the error
"The property 'Grade' on type 'Enrollment' cannot be mapped because it has been explicitly excluded from the model".
However the props Grade and enrollment have no relation to that method. They are not even in the tblStudent.
I am new to Grails and GORM and I am trying to One to Many relationship but not with default id field. Here is my scenario:
Table structure in the database:
USERPROFILE
iduserprofile
username
ROLE
idrole
rolename
USER_ROLE
iduserprofile
idrole
Domains:
class Userprofile {
long iduserprofile
String username
static mapping = {
datasource 'ALL'
id name: 'iduserprofile'
version false
}
class Role {
long idrole;
String rolename;
static mapping = {
datasource 'ALL'
id name: 'idrole'
version false
}
}
class UserRole {
Userprofile user
Role role
static mapping = {
datasource 'ALL'
version false
}
}
When I try to get the user or role object from UserRole domain, it is always looking for user_id or role_id in the USER_ROLE table.
Why is it not looking for iduserprofile or idrole? How can i change the code to look for isuserprofile or idrole?
Thanks
GORM by convention will use/generate id as identifier for your domains. If you have legacy tables or just a desire to break convention, you'll need to specify your custom column names. For example for Role mapping, add the following:
static mapping = {
datasource 'ALL'
id name: 'idrole', column: 'idrole'
version false
}
It seems to me that the easiest thing to do would be to copy your database and then change the names of the id fields if you have legacy tables. If not then just make life simple by conforming to convention.