5

Ben Aşağıdaki Fluent NHibernate Mapping ile ilgili sorun nedir?

Ben (Birçok ilişkiye Birçok)

  1. Kaynağı {ResourceId, Açıklama}
  2. Rol {RolNo, Açıklama}
  3. İzin {ResourceId, RolNo} 3 tablolar akıcı-nHibernate'de yukarıdaki tabloları haritalamaya çalışıyor. Bu benim yapmaya çalıştığım şey.

    Delete from Permission where ResourceId = 1 
    Insert into Permission (ResourceId, RoleId) values (1, 2); 
    

    yerine (doğru yolu)

    Delete from Permission where ResourceId = 1 and RoleId = 1 
    

    Neden nHibernate böyle davranmasına (yanlış)

    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. 
    

    Ama burada oluşturulan sql nedir? Haritalamanın nesi yanlış? Hatta IList yerine Set ile denedim. İşte tam kod.

    Varlıkları

    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>(); 
        } 
    } 
    

    İşte Haritalama

    // 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"); 
        } 
    } 
    

    Programı

    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"; 
         } 
        } 
    

    sayesinde Ashraf.

cevap

6

nHibernate, ebeveyn/child bildirinceye kadar tüm ilişkilerin çift yönlü olduğunu düşünür. "Ters" e ihtiyacınız vardır. Bu olmadan, "Sil" all ve "Recreate" ile yeni değer, özellikle "Çanta" tipi (varsayılan) olmak üzere iki adım atılır. ManyToMany için, varlık koleksiyonu türünü değiştirme (HashSet/Set) eşlemeyi "Çanta" olarak etkilemez. Sadece HasMany için çalışır. Haritada özellikle "AsSet" yazmanız gerekiyor. (IList/ICollection) "Çanta" ile eşleşir. Listeyi isterseniz, haritadaki "AsList" e sahip olmanız gerekir. Ancak Liste, tabloda ek dizin sütunu gerektirir.

// 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"); 
    } 
} 

Ayrıca, lazyload için Fetch.Select(). LazyLoad() koyardı.

+0

Mükemmel. Teşekkürler stoto. Kaynakımı birincil varlığım olarak kullanıyorum. Birçok haritaya çevirmek zorundayım. ResourceeMap içinde . HasManyToMany (x => x.Roles) .AsSet() Cascade.SaveUpdate() Tablo ("İzin"); RoleMap'ta . HasManyToMany (x => x.Resources) .AsSet(). Inverse(). Tablo ("İzin"); – ashraf

+0

Ayrıca biriyle ilgili blog. http://www.codinginstinct.com/2010/03/nhibernate-tip-use-set-for-many-to-many.html – ashraf

İlgili konular