在我的项目中,我有一个基类(未映射):
public abstract class BaseEntity
{
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
此外,我还有一些继承的类(它们看起来几乎一样,所以这里只有一个代码和地图)
public class User : BaseEntity
{
public virtual int UserId { get; set; }
public virtual string Login { get; set; }
public virtual string PasswordHash { get; set; }
public virtual ISet<BaseEntity> Entities { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
this.Id(x => x.UserId);
this.Map(x => x.Login);
this.Map(x => x.PasswordHash);
this.HasManyToMany<BaseEntity>(x => x.Entities);
}
}
接下来,我有一个NHibernateHelper:
public class NHibernateHelper
{
public static ISession OpenSession()
{
ISessionFactory sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"someconstring")
.ShowSql()
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())
.ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))
.BuildSessionFactory();
return sessionFactory.OpenSession();
}
}
如果我在数据库中需要像EnitiyToEntity这样的表来实现多对多关系,我如何从映射中排除BaseEntity类?
答案 0 :(得分:1)
看看这个: https://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat
如果我理解你的问题,解决方案应该是实施TPC(每个具体类别的表格)。
顺便说一下,在你的映射中你必须使用HasManyToMany
的具体类型。
例如(我猜你的用户被多个组引用):
HasManyToMany<Group>(x => x.Entities).Table("UsersGroups");
其中Group
类是这样的:
public class Group : BaseEntity
{
public virtual int GroupId { get; set; }
public virtual string PasswordHash { get; set; }
public virtual ISet<BaseEntity> Members { get; set; }
}
在GroupMap类中,您可以像这样引用用户:
HasManyToMany<User>(x => x.Members).Table("UsersGroups");
答案 1 :(得分:1)
如果你引用一个类,你必须映射它。因此将实体映射为ClassMap,将所有其他实体映射为SubclassMap。它们最终将作为union子类,每个类是一个表。不幸的是,你不能用FNH映射一个hasmanytoany。 您可以将其映射为hasmanytomany并解决它:
var config = new Configuration();
config.BeforeBindMapping += BeforeBindMapping;
_config = Fluently
.Configure(config)
...
private void BeforeBindMapping(object sender, NHCfg.BindMappingEventArgs e)
{
var userclass = e.Mapping.RootClasses.FirstOrDefault(rc => rc.name.StartsWith(typeof(User).FullName));
if (userclass != null)
{
HbmSet prop = (HbmSet)paymentclass.Properties.FirstOrDefault(rc => rc.Name == "Entities");
prop.Item = new HbmManyToAny // == prop.ElementRelationship
{
column = new[]
{
new HbmColumn { name = "entityType", notnull = true, notnullSpecified = true },
new HbmColumn { name = "entity_id", notnull = true, notnullSpecified = true }
},
idtype = "Int64",
metatype = "String",
metavalue = typeof(Entity).Assembly.GetTypes()
.Where(t => !t.IsInterface && !t.IsAbstract && typeof(Entity).IsAssignableFrom(t))
.Select(t => new HbmMetaValue { @class = t.AssemblyQualifiedName, value = t.Name })
.ToArray()
};
}
}