5

Tôi có 3 bảng (nhiều mối quan hệ)Điều gì là sai với bản đồ Fluent NHibernate sau đây?

  1. Resource {RESOURCEID, Mô tả}
  2. Vai trò {Id vai trò, mô tả}
  3. Permission {RESOURCEID, Id vai trò}

Tôi cố gắng lập bản đồ trên các bảng trong fluent-nHibernate. Đây là những gì tôi đang cố gắng làm.

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. 

Nhưng sql tạo ra ở đây là (đó là sai)

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

Thay vì (đúng cách)

Delete from Permission where ResourceId = 1 and RoleId = 1 

Tại sao nHibernate cư xử như thế này? Có gì sai với ánh xạ? Tôi thậm chí đã thử với Set thay vì IList. Đây là mã đầy đủ.

Entities

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 Đây

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

Chương trình

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

Cảm ơn, Ashraf.

Trả lời

6

nHibernate nghĩ rằng tất cả mối quan hệ là hai chiều cho đến khi bạn khai báo cha/con. Do đó bạn cần "Nghịch đảo". Nếu không có điều đó, phải mất hai bước là "Xóa" tất cả và "Tạo lại" với giá trị mới, đặc biệt là loại "Túi" (mặc định). Đối với ManyToMany, việc thay đổi kiểu tập hợp thực thể (HashSet/Set) sẽ không ảnh hưởng đến ánh xạ tới "Túi". Nó chỉ hoạt động đối với HasMany. Bạn cần cụ thể nói "AsSet" trong bản đồ. Bản đồ (IList/ICollection) thành "Túi". Nếu bạn muốn danh sách, bạn cần phải có nó "AsList" trong bản đồ. Nhưng Danh sách yêu cầu cột chỉ mục bổ sung trong bảng.

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

Ngoài ra, tôi sẽ đặt Fetch.Select(). LazyLoad() để tải xuống.

+0

Hoàn hảo. Cảm ơn stoto. Vì tôi đang sử dụng Tài nguyên làm thực thể chính của mình. Tôi cần lật nhiều bản đồ. Trong ResourceeMap. HasManyToMany (x => x.Roles) .AsSet(). Cascade.SaveUpdate(). Bảng ("Quyền"); Trong RoleMap. HasManyToMany (x => x.Resources) .AsSet(). Đảo ngược() Bảng ("Quyền"); – ashraf

+0

Cũng có ai đó viết blog về nó. http://www.codinginstinct.com/2010/03/nhibernate-tip-use-set-for-many-to-many.html – ashraf

Các vấn đề liên quan