流畅的nhibernate – 具有属性的多对多映射

我有2个主表,它们通过地图表链接如下

User [UserId,Name] Resource [ResourceId,Name] UserResourceMap [UserId,ResourceId,AccessLevel] 

具有AccessLevel的Resource和User ClassMap如何作为资源属性?

我的Domain类看起来像这样

 public class User { public virtual int UserId { get;protected set; } public virtual string Name { get;set; } } public class Resource { public virtual int ResourceId { get;protected set; } public virtual string Name { get;set; } public virtual string AccessLevel { get;set; }//Issue-populate this using fluent } 

如何在下面的代码中使用fluent映射accessLevel属性。

 public class UserMap : ClassMap { public UserMap() { Table("User"); Id(x => x.Key); Map(x=>x.Name); } } public class ResourceMap : ClassMap { public ResourceMap() { Table("Resource"); Id(x => x.Key); Map(x=>x.Name);//Need some Map Here to make a hasManyToMany Map with attribute } } 

您的域模型似乎与您的数据库模型不匹配 – Resource类具有AccessLevel属性(即每个资源一个AccessLevel),但在DB模型中,AccessLevel是地图表上的一列(即每个用户 – 资源关系一个AccessLevel)。

假设DB模型是正确的模型(相当简单)映射方式,这将是引入这样的类。

 public class UserResource { public virtual int UserResourceId { get; protected set; } public virtual User User { get; set; } public virtual Resource { get; set; } public virtual string AccessLevel { get; set; } } 

并以这种方式映射:

 public class UserResourceMap : ClassMap { public UserResourceMap() { Table("UserResourceMap"); Id(x => x.UserResourceId); References(x => x.User).UniqueKey("UniqueUserAndResource"); References(x => x.Resource).UniqueKey("UniqueUserAndResource"); Map(x => x.AccessLevel); } } 

如果您想要双向关联,您还可以在User和/或Resource上添加Collection属性,并使用HasMany(…)映射这些属性.Inverse()。 当然,这种映射会在UserResourceMap表中引入一个新的UserResourceId列(使用由User和Resource组成的复合键可以减轻这种情况)。

另一种解决方案是添加EntityMap关联。 如果关联由User拥有,则它将是Dictionary 属性。 这样的事情可能会成功:

 public class User { public virtual int UserId { get; protected set; } public virtual string Name { get; set; } public virtual Dictionary Resources { get; set; } // Resource -> AccessLevel } public class UserMap : ClassMap { public UserMap() { Table("User"); Id(x => x.UserId); Map(x => x.Name); HasMany(x => x.Resources).AsEntityMap().Element("AccessLevel"); } } 

正如您在数据库模式中正确识别的那样,这不是纯粹的多对多关系 – 它是两个一对多关系,因为中间表具有属性(访问级别)。

因此,我认为您的域名缺少实体 – 您的模型中似乎没有任何关系在用户和他们可以访问的资源之间。

这样的事情怎么样:

 public class User { public virtual int Id { get;protected set; } public virtual string Name { get;set; } public virtual ICollection UserResources { get; set;} } public class UserResource { public virtual int Id { get; protected set; } public virtual User User { get; set;} public virtual Resource Resource { get; set;} public virtual string AccessLevel { get; set;} } public class Resource { public virtual int Id { get;protected set; } public virtual string Name { get;set; } } 

和映射如:

 public class UserMap : ClassMap { public UserMap() { Id(x => x.Id); Map(x => x.Name); HasMany(x => x.UserResource) .AsSet() .Inverse() .Cascade.AllDeleteOrphan(); } } public class UserResourceMap : ClassMap { public UserResourceMap() { Table("UserResourceMap"); Id(x => x.Id); References(x => x.User).Not.Nullable(); References(x => x.Resource).Not.Nullable(); Map(x => x.AccessLevel); } } public class ResourceMap : ClassMap { public ResourceMap() { Cache.ReadOnly(); Id(x => x.Id); Map(x => x.Name); } }