Link table in EntityFramework - c#

I'm using PostGre for my RoleProvider.
That my DbContext.
public class MembershipDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<RoleUser> RoleUsers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Role>().ToTable("Roles");
modelBuilder.Entity<RoleUser>().ToTable("RoleUser");
}
}
And models:
public class User
{
public virtual ICollection<Role> Roles { get; set; }
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
}
public class Role
{
public virtual ICollection<User> Users { get; set; }
public int RoleId { get; set; }
public string Name { get; set; }
}
public class RoleUser
{
[Key, ForeignKey("Role"), Column(Order = 0)]
public int RoleId { get; set; }
[Key, ForeignKey("User"), Column(Order = 1)]
public int UserId { get; set; }
public virtual Role Role { get; set; }
public virtual User User { get; set; }
}
Problem sample:
var dbContext = new MembershipDbContext();
var users = dbContext.Users.ToList();
var roles = dbContext.Roles.ToList();
//it says: "ERROR: 42P01: relation "dbo.RoleUser1" not exist"
var rolesOfFirstUser = users[0].Roles;//not working
var usersOfFirstRole = roles[0].Users;//not working
var roleUsers = dbContext.RoleUsers.ToList();//all links works perfect
What should I do to make it work?
This answer fixes it, but I have no idea where is EF creates "RoleUsers" link table. I need it.
p.s. Sorry for bad english.

You should actually make those collections (on both files) point to RoleUser, i.e. the following:
public virtual ICollection<RoleUser> RoleUsers {get;set;}

Related

Is there a way to Ignore specific property in asp.net core Include function from many to many relationship

I am working on Asp.net core 5 Web-api, I am using many to many relationship between User entity and Permission entity, and I need to load users permission from the database using eager loading but the data is returning a looped information including users full information but I only load the permissions. I am using a Dto to return the Json data. Here is my models and my code
Permission Model
public class Permission
{
public int Id { get; set; }
public string ClaimName { get; set; }
public IList<UserPermission> UserPermissions { get; set; }
}
UserPermission model
public class UserPermission
{
public int UserId { get; set; }
public AppUser AppUser { get; set; }
public int PermissionId { get; set; }
public Permission Permission { get; set; }
}
User model
public class AppUser
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Photo> Photos { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public DateTime LastActive { get; set; }
public IList<UserPermission> UserPermissions { get; set; }
public bool Status { get; set; }
}
My user Dto
public class UserDto
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Photo> Photos { get; set; }
public ICollection<UserPermission> UserPermissions { get; set; }
public string Token { get; set; }
}
My function
var sss = _context.UserPermissions
.Include(l => l.Permission)
.Where(v => v.UserId == user.Id)
.ToList();
Use [JsonIgnore] on the properties that we want to exclude.
note that we should use "using Newtonsoft.Json" name space not using "System.Text.Json.Serialization"

EF Code First Many-to-Many Relationship with ASP.NET Identity Table at one Side

I am trying to accomplish many-to-many relationship using code-first EF with ASP.NET Identity table at one side. The join table is not generated in the DB, though. What am I missing? Here are my model classes:
AppUser.cs:
public class AppUser : IdentityUser
{
public AppUser()
{
Notes = new HashSet<Note>();
}
public DateTime? LastSuccessfulLoginDate { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
and
Note.cs:
public class Note
{
public Note() {
NoteAssignedToUsers = new HashSet<AppUser>();
}
[Key]
public int NoteID { get; set; }
[Required]
public int FileID { get; set; }
[Required]
public string Content { get; set; }
[Required]
public Importance? Importance { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy HH.mm}")]
public DateTime AddedOn { get; set; }
[Required]
public string CreatorID { get; set; }
[ForeignKey("FileID")]
public virtual OAFile OAFile { get; set; }
[ForeignKey("CreatorID")]
public virtual AppUser CreatedBy { get; set; }
public virtual ICollection<AppUser> NoteAssignedToUsers { get; set; }
}
In your dbcontext you can configure:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Note>()
.HasMany<AppUser>(s => s.NoteAssignedToUsers )
.WithMany(c => c.Notes)
.Map(cs =>
{
cs.MapLeftKey("AppUserId");
cs.MapRightKey("NoteId");
cs.ToTable("AppUsersNotes");
});
}

How to map a List in Entity Framework?

I have two classes: Role and RoleViewModel.
Role class
public partial class Role
{
public Role()
{
this.Users = new HashSet<User>();
}
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
RoleViewModel class
public class RoleViewModel
{
public RoleViewModel()
{
this.Users = new HashSet<UserViewModel>();
}
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<UserViewModel> Users { get; set; }
}
Now, I am trying to fetch a list of Role from database and map it to a list of RoleViewModel.
public static List<RoleViewModel> GetRolesService()
{
List<Role> roles =MainRepository.GetUserRoles();
var rolesVM = Mapper.Map<List<Role>, List<RoleViewModel>>(roles);
return rolesVM;
}
The problem is that rolesVM list always have Count=0, and I don't know why.
Thanks in advance!.
One solution is to ignore nested dependencies.
Mapper.CreateMap<Role, RoleViewModel>().ForMember(c=>c.Users,option=>option.Ignore());

Entity Framework - Multiple navigation property

I started working with Entity Framework and I have one BIG problem. I want a many-to-many relation between entities User and Role.
So I created 3 tables User, Role, UserRoles
Next I created 3 entities:
public class User
{
public virtual int UserId { get; protected set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual DateTime CreateDate { get; set; }
public virtual ICollection<UserRole> Roles { get; set; }
public virtual ICollection<UserRole> CreatedRoles { get; set; }
}
public class Role
{
public virtual int RoleId { get; protected set; }
public virtual string Name { get; set; }
}
public class UserRole
{
public virtual int UserRoleId { get; protected set; }
public virtual int UserId { get; set; }
public virtual User User { get; set; }
public virtual int RoleId { get; set; }
public virtual Role Role { get; set; }
public virtual DateTime CreateDate { get; set; }
public virtual int CreateUserId { get; set; }
public virtual User CreateUser { get; set; }
}
I want to separate mapped user from created user. And In this step Entity Framework start to throw a bugs.
Next I want navigate from User object to his mapped roles and to his created mappings.
Can I configure Entity Framework to do these things?
You should apply InverseProperty attribute:
public class User
{
public virtual int UserId { get; protected set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual DateTime CreateDate { get; set; }
[InverseProperty("User")]
public virtual ICollection<UserRole> Roles { get; set; }
[InverseProperty("CreateUser")]
public virtual ICollection<UserRole> CreatedRoles { get; set; }
}

Make a good relation between group, users with an owner with entity framework code first

I would try to make a relation between two entities : A goup (with an owner and users) and user (which belongs to a unique group). Code :
public class User
{
public int Id { get; set; }
public int GroupId { get; set; }
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}
I don't arrive with data annotation to make it corectly.
Thank you so much for your propositions
A solution that works for me :
public class User
{
public int Id { get; set; }
public int? GroupId { get; set; }
[InverseProperty("Users")]
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public int? OwnerId { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}

Categories

Resources