Delete on Many to Many Relationship using Fluent Nhibernate - nhibernate

User Class
public class User
{
public virtual Guid UserID { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual string FullName { get; set; }
public virtual string Email { get; set; }
public virtual TimeSpan LastLogin { get; set; }
public virtual bool IsActive { get; set; }
public virtual DateTime CreationDate { get; set; }
public virtual IList<Role> Roles { get; set; }
public User()
{
Roles = new List<Role>();
}
public virtual void AddRoles(Role role)
{
role.Users.Add(this);
Roles.Add(role);
}
}
Role Class
public class Role
{
public virtual int? RoleID { get; set; }
public virtual string RoleName { get; set; }
public virtual bool IsActive { get; set; }
public virtual string Description { get; set; }
public virtual IList<User> Users { get; set; }
public virtual IList<Role> Roles { get; set; }
public Role()
{
Users = new List<User>();
}
}
UserMap Class
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("tblUsers");
Id(user => user.UserID).GeneratedBy.Guid();
Map(user => user.UserName).Not.Nullable();
Map(user => user.Password).Not.Nullable();
Map(user => user.FullName).Not.Nullable();
Map(user => user.Email).Not.Nullable();
//Map(user => user.LastLogin).Nullable();
Map(user => user.IsActive).Not.Nullable();
Map(user => user.CreationDate).Not.Nullable();
HasManyToMany<Role>(x => x.Roles).Table("tblUserInRoles")
.ParentKeyColumn("UserID")
.ChildKeyColumn("RoleID")
.Cascade.All()
//.AsSet()
//.Inverse()
.Not.LazyLoad();
}
}
RoleMap Class
public class RoleMap : ClassMap<Role>
{
public RoleMap()
{
Table("tblRoles");
Id(role => role.RoleID).GeneratedBy.Identity();
Map(role => role.RoleName).Not.Nullable();
Map(role => role.IsActive).Not.Nullable();
Map(role => role.Description).Not.Nullable();
HasManyToMany<User>(x => x.Users)
.Table("tblUserInRoles")
.ParentKeyColumn("RoleID")
.ChildKeyColumn("UserID")
.Cascade.All()
.Inverse()
.Not.LazyLoad();
}
}
My questions are:
I want to delete all roles of particular user? [Answered by danyolgiax]
Get roles of user
Can Any one guide me..

try .Inverse() on User (not on Role) and then:
user.Roles.Clear();
yourNhSession.SaveOrUpdate(user);
update
User user= yourNhSession.Get<User>(userId);
IList<Role> role= user.Roles;

Related

Fluent NHibernate Mapping multiple tables has relation and joined to each other

As you see the models have references as one to many. list of project is not mapped here. there are more than one project and the project has more than one role and the role has more than one permission.
error is persister system not avialable.
can anyone look up and help me ?
public class Permission
{
public virtual int MId { get; set; }
public virtual string Id { get; set; }
public virtual bool View { get; set; }
public virtual bool Add { get; set; }
public virtual bool Edit { get; set; }
public virtual bool Delete { get; set; }
public virtual Role Roles { get; set; }
}
public class Role
{
public virtual int RId { get; set; }
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Site_Id { get; set; }
public virtual string Site_Name { get; set; }
public virtual string Domain { get; set; }
public virtual List<Permission> permissions { get; set; }
public virtual Project Project { get; set; }
}
public class Project
{
public virtual int PId { get; set; }
public virtual string Id { get; set; }
public virtual string Name { get; set; }
public virtual List<Role> Roles { get; set; }
}
Mappings
public class PermissionMapping : ClassMap<Permission>
{
public PermissionMapping()
{
Table("ModulePermissions");
Id(u => u.MId).GeneratedBy.Identity();
Map(u => u.Id).Column("ModuleName");
Map(u => u.View);
Map(u => u.Edit);
Map(u => u.Add);
Map(u => u.Delete);
References(x => x.Roles).Column("RolePermissionId");
}
}
public class RoleMapping : ClassMap<Role>
{
public RoleMapping()
{
Table("ModuleRole");
Id(u => u.RId).GeneratedBy.Identity();
Map(u => u.Name);
Map(u => u.Site_Id).Column("SiteId");
Map(u => u.Site_Name).Column("SiteName");
Map(u => u.Domain);
References(x => x.Project).Column("RoleProjectId");
HasMany(u => u.permissions).KeyColumn("RolePermissionId").Inverse().Cascade.All().Not.LazyLoad();
}
}
public class ProjectsMapping : ClassMap<Project>
{
public ProjectsMapping()
{
Table("Projects");
Id(u => u.PId).GeneratedBy.Identity();
Map(u => u.Id).Column("ApiProjectId");
Map(u => u.Name);
HasMany(u => u.Roles).KeyColumn("RoleProjectId").Inverse().Cascade.All().Not.LazyLoad();
}
}

Invalid Column name when adding Migration

I am using .NET 5 and getting this error when I try to add a column to my database. The only fixes I found so far was to set the right startup project, but since I dont have two projects I dont know how to fix it.
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: Invalid column name 'EspStartTime'.
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
ApplicationDbContext
internal class TaskEntityTypeConfiguration : IEntityTypeConfiguration<Task>
{
public void Configure(EntityTypeBuilder<Task> builder)
{
builder.Property(e => e.Description)
.HasConversion(
xml => xml.ToString(),
xml => xml != null ? XElement.Parse(xml) : null)
.HasColumnType("xml");
}
}
internal class StudentAssignedTaskEntityTypeConfiguration : IEntityTypeConfiguration<StudentAssignment>
{
public void Configure(EntityTypeBuilder<StudentAssignment> builder)
{
builder.Property(e => e.FeedbackXml)
.HasConversion(
xml => xml.ToString(),
xml => xml != null ? XElement.Parse(xml) : null)
.HasColumnType("xml");
builder.Property(e => e.StudentSubmissionAttachmentsXml)
.HasConversion(
xml => xml.ToString(),
xml => xml != null ? XElement.Parse(xml) : null)
.HasColumnType("xml");
builder.Property(e => e.StudentSubmissionXml)
.HasConversion(
xml => xml.ToString(),
xml => xml != null ? XElement.Parse(xml) : null)
.HasColumnType("xml");
}
}
public class ApplicationDbContext : IdentityApplicationDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
//this.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
public static readonly ILoggerFactory Factory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseLoggerFactory(Factory);
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
foreach (var relationship in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
relationship.DeleteBehavior = DeleteBehavior.Restrict;
builder.Entity<ApplicationUser>().HasMany(x => x.TeacherGroups).WithOne(x => x.Teacher).OnDelete(DeleteBehavior.SetNull);
builder.Entity<ApplicationUser>().HasMany(x => x.StudentGroups).WithMany(x => x.Students);
builder.Entity<SchoolClassStudentTerm>().HasKey(x => new { x.StudentId, x.SchoolClassId, x.TermId });
builder.ApplyConfiguration(new TaskEntityTypeConfiguration());
builder.ApplyConfiguration(new StudentAssignedTaskEntityTypeConfiguration());
builder.Entity<GroupAssignment>().HasOne(x => x.ClassroomGroup).WithMany(x => x.GroupAssignments).OnDelete(DeleteBehavior.Cascade);
builder.Entity<GroupAssignment>().HasMany(x => x.StudentAssignments).WithOne(x => x.GroupAssignment).OnDelete(DeleteBehavior.Cascade);
builder.Entity<GroupAssignment>().HasOne(x => x.Task).WithMany(x => x.GroupAssignments).OnDelete(DeleteBehavior.Cascade);
builder.Entity<SchoolClassStudentTerm>().HasOne(x => x.Student).WithMany(x => x.SchoolClassStudentTerms).OnDelete(DeleteBehavior.Cascade);
builder.Entity<StudentAssignment>().HasOne(x => x.Student).WithMany().OnDelete(DeleteBehavior.SetNull);
builder.Entity<GroupAssignment>().HasOne(x => x.Creator).WithMany(x => x.CreatedGroupAssignments).OnDelete(DeleteBehavior.SetNull);
builder.Entity<SchoolClass>().HasMany(x => x.SchoolClassStudentTerms).WithOne(x => x.SchoolClass);
// see https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x?view=aspnetcore-5.0#add-identityuser-poco-navigation-properties
builder.Entity<ApplicationUser>().HasMany(x => x.UserRoles).WithOne(x => x.User)
.HasForeignKey(x => x.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
}
public DbSet<SchoolClassStudentTerm> SchoolClassStudentTerms { get; set; }
public DbSet<Term> Terms { get; set; }
public DbSet<StudentAssignment> StudentAssignments { get; set; }
public DbSet<ClassroomGroup> ClassroomsGroups { get; set; }
public DbSet<SchoolClass> SchoolClasses { get; set; }
public DbSet<GroupAssignment> GroupAssignments { get; set; }
public DbSet<Task> Tasks { get; set; }
public DbSet<Subject> Subjects { get; set; }
IdentityDbContext
// see https://learn.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-5.0
public abstract class IdentityApplicationDbContext : IdentityDbContext<
ApplicationUser, ApplicationRole, string,
IdentityUserClaim<string>, ApplicationUserRole, IdentityUserLogin<string>,
IdentityRoleClaim<string>, IdentityUserToken<string>>
{
public IdentityApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>(b =>
{
// Each User can have many entries in the UserRole join table
b.HasMany(e => e.UserRoles)
.WithOne(e => e.User)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
modelBuilder.Entity<ApplicationRole>(b =>
{
// Each Role can have many entries in the UserRole join table
b.HasMany(e => e.UserRoles)
.WithOne(e => e.Role)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
});
}
}
ApplicationUser
public class ApplicationUser : IdentityUser
{
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
public virtual ICollection<ClassroomGroup> TeacherGroups { get; set; }
public virtual ICollection<ClassroomGroup> StudentGroups { get; set; }
public virtual ICollection<Task> CreatedTasks { get; set; }
public virtual ICollection<SchoolClassStudentTerm> SchoolClassStudentTerms { get; set; }
public virtual ICollection<GroupAssignment> CreatedGroupAssignments { get; set; }
public bool Disabled { get; set; }
public String FullName { get; set; }
public DateTime? EspStartTime { get; set; }
}
ClassroomGroup
public class ClassroomGroup
{
public int SubjectId { get; set; }
public virtual Subject Subject { get; set; }
public virtual SchoolClass SchoolClass { get; set; }
public int SchoolClassId { get; set; }
public String TeacherId { get; set; }
public virtual ApplicationUser Teacher { get; set; }
public int Id { get; set; }
public String Title { get; set; }
public virtual ICollection<ApplicationUser> Students { get; set; }
public int TermId { get; set; }
public virtual Term Term { get; set; }
public virtual ICollection<GroupAssignment> GroupAssignments { get; set; }
}

Fluent NHibernate - 1:1 Relationship with Nullable Field

Given the following model, I want to be able to enter a new WriteOffApprovalUser and have the Employee field be null. This is a 1:1 or null relationship.
public class WriteOffApprovalUser
{
public virtual string UserName { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
public virtual string EmployeeID { get; set; }
public virtual string EmployeeStatusCode { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string JobTitle { get; set; }
public virtual string Division { get; set; }
public virtual string Department { get; set; }
public virtual string Location { get; set; }
public virtual string City { get; set; }
public virtual string DeskLocation { get; set; }
public virtual string MailID { get; set; }
public virtual string Phone { get; set; }
public virtual string PreferredName { get; set; }
public virtual string Fax { get; set; }
public virtual string SecCode { get; set; }
public virtual string SupervisorID { get; set; }
public virtual string UserId { get; set; }
}
Class Maps
public class WriteOffApprovalUserMap : ClassMap<WriteOffApprovalUser>
{
public WriteOffApprovalUserMap()
{
Table("WRITEOFF_APPROVAL_USER");
Id(x => x.UserName).Column("USER_NAME");
//Map(x => x.Employee).Nullable();
HasOne(x => x.Employee)
.Class<Employee>()
.Constrained()
.Cascade.SaveUpdate()
.PropertyRef("UserId");
}
}
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Table("ADP_EMPLOYEE");
Id(x => x.EmployeeID).Column("EMPLID").GeneratedBy.Native("");
Map(x => x.FirstName).Column("FIRST_NAME");
Map(x => x.LastName).Column("LAST_NAME");
Map(x => x.PreferredName).Column("PREFERRED_NAME");
Map(x => x.UserId).Column("USER_ID");
}
}
Query/Save
using (var session = SessionProvider.GetSession())
{
using (var tx = session.BeginTransaction())
{
var user = new WriteOffApprovalUser() { UserName = "SAMSTR" };
session.Save(user);
tx.Commit();
}
}
This complains that Employee is null. How do I specify that Employee can be null?
Also, do all Id fields have to be integral? A lot of the keys on our tables are strings.
First off all if you put it as 1:1 it shouldn't be NULL because it's not correct design.
But here is an example of how to do so:
1) One way
HasOne(x => x.Employee)
.Class<Employee>().Nullable().NotFound.Ignore().PropertyRef("UserId");
2) Second way
References(x => x.Category).Column("UserId").Nullable().NotFound.Ignore();

Fluent NHibernate: How to create circular one-to-one mapping?

public class AdminUser
{
public virtual int Id { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual bool IsLocked { get; set; }
public virtual AdminUser Creator { get; set; }
public virtual DateTime CreationDate { get; set; }
}
public class AdminUserMapping : ClassMap<AdminUser>
{
public AdminUserMapping()
{
Id(c => c.Id).GeneratedBy.Native();
Map(c => c.UserName).Not.Nullable();
Map(c => c.Password).Not.Nullable();
Map(c => c.IsLocked).Not.Nullable();
Map(c => c.CreationDate).Not.Nullable();
//HasOne<AdminUser>(... ?)
}
}
Hi i have class like above, and i want to create one-to-one mapping for "Creator" property on same class
how can i do this?
Try this:
References(x => x.Creator);
Make sure that you have a column named Creator_Id on your table. If you don't, you can use:
References(x => x.Creator).Column("YourColumnName")

How am I supposed to query for a persisted object's property's subproperty in nhibernate?

I'm feeling dumb.
public class Uber
{
public Foo Foo { get; set; }
public Bar Bar { get; set; }
}
public class Foo
{
public string Name { get; set; }
}
...
var ubercharged = session.CreateCriteria(typeof(Uber))
.Add(Expression.Eq("Foo.Name", "somename"))
.UniqueResult<Uber>();
return ubercharged;
This throws a "could not resolve property" error.
What am I doing wrong? I want to query for an Uber object that has a property Foo which has a Name of "somename".
updated with real life example, repository call, using fluent nhibernate:
public UserPersonalization GetUserPersonalization(string username)
{
ISession session = _sessionSource.GetSession();
var personuser = session.CreateCriteria(typeof(UserPersonalization))
.Add(Expression.Eq("User.Username", username))
.UniqueResult<UserPersonalization>();
return personuser;
}
The classes/mappings:
public class User
{
public virtual Guid UserId { get; set; }
public virtual string Username { get; set; }
public virtual string Email { get; set; }
public virtual string PasswordHash { get; set; }
public virtual string PasswordSalt { get; set; }
public virtual bool IsLockedOut { get; set; }
public virtual bool IsApproved { get; set; }
}
public class Person
{
public virtual int PersonId { get; set; }
public virtual string Name { get; set; }
public virtual Company Company { get; set; }
}
public class UserPersonalization
{
public virtual int UserPersonalizationId { get; set; }
public virtual Person Person { get; set; }
public virtual User User { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.UserId).GeneratedBy.Guid().ColumnName("UserId");
Map(x => x.Username);
Map(x => x.PasswordHash);
Map(x => x.PasswordSalt);
Map(x => x.Email);
Map(x => x.IsApproved);
Map(x => x.IsLockedOut);
}
}
public class UserPersonalizationMap : ClassMap<UserPersonalization>
{
public UserPersonalizationMap()
{
WithTable("UserPersonalization");
Id(x => x.UserPersonalizationId).ColumnName("UserPersonalizationId");
References(x => x.Person).ColumnName("PersonId");
References(x => x.User).ColumnName("UserId");
}
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Id(x => x.PersonId).ColumnName("PersonId");
Map(x => x.Name);
References(x => x.Company).ColumnName("CompanyId");
}
}
Try this:
var ubercharged = session.CreateCriteria(typeof(Uber))
.CreateCriteria("Foo")
.Add(Restrictions.Eq("Name", "somename"))
.UniqueResult<Uber>();
Can you sort using "ubercharged.AddOrder(Order.asc("Foo.Name")) syntax? This syntax should work in NHib 2.01. If not, your maps are not working correctly.
Stuart's answer should work fine for you though.