【问题标题】:What is wrong with the following Fluent NHibernate Mapping?以下 Fluent NHibernate 映射有什么问题?
【发布时间】:2011-02-01 00:18:24
【问题描述】:

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

  1. 资源 {ResourceId, Description}
  2. 角色 {RoleId, 描述}
  3. 权限 {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";
        }
    }

谢谢, 阿什拉夫。

【问题讨论】:

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


    【解决方案1】:

    nHibernate 认为所有关系都是双向的,直到您声明父/子。所以您需要“反向”。没有它,它需要两个步骤,即“删除”全部和“重新创建”新值,尤其是“袋”类型(默认)。对于 ManyToMany,更改实体集合类型(HashSet/Set)不会影响到“Bag”的映射。它仅适用于 HasMany。您需要在地图中特别说“AsSet”。 (IList/ICollection) 映射到“Bag”。如果你想要 List,你需要在 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() 用于延迟加载。

    【讨论】:

    • 完美。谢谢斯托托。因为我使用 Resource 作为我的主要实体。我需要翻转多对多映射。在资源地图中。 HasManyToMany(x => x.Roles).AsSet().Cascade.SaveUpdate().Table("Permission");在角色映射中。 HasManyToMany(x => x.Resources).AsSet().Inverse().Table("Permission");
    • 还有人写博客。 codinginstinct.com/2010/03/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2011-04-10
    相关资源
    最近更新 更多