asp.net-mvc - 以下 Fluent NHibernate Mapping 有什么问题?

标签 asp.net-mvc nhibernate fluent-nhibernate nhibernate-mapping

我有 3 个表(多对多关系)

  • 资源 {ResourceId, Description}
  • 角色 {RoleId, Description}
  • 权限 {ResourceId, RoleId}

  • 我试图在 fluent-nHibernate 中映射上面的表格。这就是我想要做的。
    var aResource = session.Get<Resource>(1); // 2 Roles associated (Role 1 and 2)
    var aRole = session.Get<Role>(1);
    aResource.Remove(aRole); // I try to delete just 1 role from permission.
    

    但是这里生成的sql是(错误的)
    Delete from Permission where ResourceId = 1
    Insert into Permission (ResourceId, RoleId) values (1, 2);
    

    而不是(正确的方式)
        Delete from Permission where ResourceId = 1 and RoleId = 1
    

    为什么 nHibernate 表现得像这样?映射有什么问题?我什至尝试使用 Set 而不是 IList。这是完整的代码。

    实体
    public class Resource
    {
        public virtual string Description { get; set; }
        public virtual int ResourceId { get; set; }
        public virtual IList<Role> Roles { get; set; }
    
        public Resource()
        {
            Roles = new List<Role>();
        }
    }
    
    public class Role
    {
        public virtual string Description { get; set; }
        public virtual int RoleId { get; set; }
        public virtual IList<Resource> Resources { get; set; }
    
        public Role()
        {
            Resources = new List<Resource>();
        }
    }
    

    在这里映射
    // Mapping ..
    public class ResourceMap : ClassMap<Resource>
    {
        public ResourceMap()
        {
            Id(x => x.ResourceId);
            Map(x => x.Description);
            HasManyToMany(x => x.Roles).Table("Permission");
        }
    }
    
    public class RoleMap : ClassMap<Role>
    {
        public RoleMap()
        {
            Id(x => x.RoleId);
            Map(x => x.Description);
            HasManyToMany(x => x.Resources).Table("Permission");
        }
    }
    

    程序
        static void Main(string[] args)
        {
            var factory = CreateSessionFactory();
            using (var session = factory.OpenSession())
            {
                using (var tran = session.BeginTransaction())
                {
                    var aResource = session.Get<Resource>(1);
                    var aRole = session.Get<Role>(1);
                    aResource.Remove(aRole);
                    session.Save(a);
                    session.Flush(); 
                    tran.Commit();
                }
            }
        }
        private static ISessionFactory CreateSessionFactory()
        {
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008
                .ConnectionString("server=(local);database=Store;Integrated Security=SSPI"))
                .Mappings(m => 
                    m.FluentMappings.AddFromAssemblyOf<Program>()
                    .Conventions.Add<CustomForeignKeyConvention>())
                .BuildSessionFactory();
        }
    
        public class CustomForeignKeyConvention : ForeignKeyConvention
        {
            protected override string GetKeyName(FluentNHibernate.Member property, Type type)
            {
                return property == null ? type.Name + "Id" : property.Name + "Id";
            }
        }
    

    谢谢,
    阿什拉夫。

    最佳答案

    nHibernate 认为所有关系都是双向的,直到你声明父/子。所以你需要“反向”。没有它,它需要两个步骤,即“全部删除”和“使用新值重新创建”,尤其是“包”类型(默认)。对于 ManyToMany,更改实体集合类型(HashSet/Set)不会影响到“Bag”的映射。它仅适用于 HasMany。您需要在 map 中特别说“AsSet”。 (IList/ICollection) 映射到“包”。如果你想要列表,你需要在 map 中拥有“AsList”。但是 List 需要表中的额外索引列。

    // Mapping .. 
    public class ResourceMap : ClassMap<Resource> 
    { 
        public ResourceMap() 
        { 
            Id(x => x.ResourceId); 
            Map(x => x.Description); 
            HasManyToMany(x => x.Roles).AsSet().Inverse().Table("Permission");
        } 
    } 
    
    public class RoleMap : ClassMap<Role> 
    { 
        public RoleMap() 
        { 
            Id(x => x.RoleId); 
            Map(x => x.Description); 
            HasManyToMany(x => x.Resources).AsSet().Cascade.SaveUpdate().Table("Permission");
        } 
    } 
    

    另外,我会将 Fetch.Select().LazyLoad() 用于延迟加载。

    关于asp.net-mvc - 以下 Fluent NHibernate Mapping 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2520607/

    相关文章:

    c# - 无法将 NULL 值插入到列、表中;列不允许为空...但是该列是主键并且具有自动增量属性

    c# - 带有 nhibernate/fluent 的枚举标志

    asp.net-mvc - 我的一些 asp mvc 4 包停止工作

    hibernate - NHibernate:(一或零)到(一或零)映射

    c# - NHibernate - 如何处理 NonUniqueObjectException?

    c# - 如何将 'where not in' 转换为子查询表不是实体的 NHibernate 查询?

    c# - Fluent Nhibernate ManyToMany 集合 - 不保存关联

    nhibernate - FluentNHibernate 映射需要帮助

    asp.net-mvc - 有没有办法避免我在 MVC Razor View 中重复我的代码?

    asp.net-mvc - 同一页面中的多个 View MVC ASP.NET