我有2个主表,它们通过地图表链接,如下所示
User [UserId,Name]
Resource [ResourceId,Name]
UserResourceMap [UserId,ResourceId,AccessLevel]
如何将具有AccessLevel的资源和用户类Map作为资源属性?
我的域类看起来像这样
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<User>
{
public UserMap()
{
Table("User");
Id(x => x.Key);
Map(x=>x.Name);
}
}
public class ResourceMap : ClassMap<Resource>
{
public ResourceMap()
{
Table("Resource");
Id(x => x.Key);
Map(x=>x.Name);//Need some Map Here to make a hasManyToMany Map with attribute
}
}
答案 0 :(得分:7)
您的域模型似乎与您的数据库模型不匹配 - Resource类具有AccessLevel属性(即每个资源一个AccessLevel),但在DB模型中,AccessLevel是地图表上的一列(即每个用户资源一个AccessLevel)关系)。
假设数据库模型是正确的模型(一种相当简单的)映射方式,那就是引入这样的类。
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<UserResource> {
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&lt; Resource,string&gt;属性。这样的事情可能会起到作用:
public class User {
public virtual int UserId { get; protected set; }
public virtual string Name { get; set; }
public virtual Dictionary<Resource, string> Resources { get; set; } // Resource -> AccessLevel
}
public class UserMap : ClassMap<User> {
public UserMap() {
Table("User");
Id(x => x.UserId);
Map(x => x.Name);
HasMany<Resource, string>(x => x.Resources).AsEntityMap().Element("AccessLevel");
}
}
答案 1 :(得分:5)
正如您在数据库模式中正确识别的那样,这不是纯粹的多对多关系 - 它是两个一对多关系,因为中间表具有属性(访问级别)。
因此,我认为您的域名缺少实体 - 您的模型中似乎没有任何关系在用户和他们可以访问的资源之间。
这样的事情怎么样:
public class User
{
public virtual int Id { get;protected set; }
public virtual string Name { get;set; }
public virtual ICollection<UserResource> 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<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.Name);
HasMany(x => x.UserResource)
.AsSet()
.Inverse()
.Cascade.AllDeleteOrphan();
}
}
public class UserResourceMap : ClassMap<UserResource>
{
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<Resource>
{
public ResourceMap()
{
Cache.ReadOnly();
Id(x => x.Id);
Map(x => x.Name);
}
}