![](/img/trans.png)
[英]Fluent NHibernate table-per-inheritance (TPH) mapping for multi class in the hierarchy
[英]Nhibernate inheritance mapping mixing Type-Per-Hierarchy with Type-Per-Class?
我正在尝试映射此类:
public interface IBusinessObject
{
Guid Id { get; set; }
}
public class Product
{
public virtual Guid Id { get; set; }
public virtual int ProductTypeId { get; set; }
}
public class ProductWeSell : Product, IBusinessObject
{
}
public class ProductWeDontSell : Product
{
}
到具有2个表的数据库:
[BusinessObject] COLUMNS ([Id])
[Product] COLUMNS ([Id], [ProdyctTypeId])
我想为BusinessObject创建每个类的类型,并为产品创建每个层次的类型。 这应该导致此行为:
从逻辑上讲,HBM映射应为:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="IBusinessObject" table="BusinessObject">
<joined-subclass name="ProductWeSell" table="Product"/>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" discriminator-value="null" name="Product" table="Product">
<discriminator type="String">
<column name="ProductTypeId" not-null="false" />
</discriminator>
<subclass name="ProductWeDontSell" discriminator-value="2" />
<subclass name="ProductWeSell" discriminator-value="1" />
</class>
</hibernate-mapping>
但是出现{“重复的类/实体映射ProductWeSell”}错误。
我相当确定,使用Fluent NHibernate无法做到这一点。 在尝试提出一种方法时,我创建了以下TestFixture。 另外,我不确定您要映射的内容。 如果要在系统中的每个实体中使用它,则IBusinessObject似乎是多余的(CreateQuery(“ from object”)将返回从object继承的每个实体,即所有实体)
注意:当前,这在IBusinessObject查询上失败(因为它应该被映射,因为它没有被映射)。 我不太确定为什么不映射IBusinessObject接口就无法解决这个问题,因为隐式多态性似乎应该涵盖这一点(请参阅: http : //nhibernate.info/doc/nh/en/index.html#inheritace-mixingpolymorphism )。
[TestFixture]
public class TestFixture
{
private ISessionFactory _sessionFactory;
private ISession _session;
[SetUp]
public void Setup()
{
var fluentConfig = Fluently.Configure().Database(() => SQLiteConfiguration.Standard.InMemory().Provider<TestConnectionProvider>())
.Mappings(x=>x.FluentMappings.Add<ProductMap>()
.Add<ProductWeSellMap>()
.Add<ProductWeDontSellMap>());
var nhConfig = fluentConfig.BuildConfiguration();
_sessionFactory = fluentConfig.BuildSessionFactory();
var schema = new SchemaExport(nhConfig);
schema.Execute(false, true, false);
_session = _sessionFactory.OpenSession();
}
[Test]
public void SomeTest()
{
using (var itx = this._session.BeginTransaction())
{
var productSold = new ProductWeSell();
var productNotSold = new ProductWeDontSell();
_session.Save(productNotSold);
_session.Save(productSold);
itx.Commit();
}
using (var itx = this._session.BeginTransaction())
{
Assert.That(_session.CreateQuery("from ProductWeSell").List(), Has.Count.EqualTo(1));
Assert.That(_session.CreateQuery("from ProductWeDontSell").List(), Has.Count.EqualTo(1));
Assert.That(_session.CreateQuery("from IBusinessObject").List(), Has.Count.EqualTo(1));
Assert.That(_session.CreateQuery("from Product").List(), Has.Count.EqualTo(2));
}
}
}
public interface IBusinessObject
{
Guid Id { get; set; }
}
public class Product
{
public virtual Guid Id { get; set; }
public virtual int ProductTypeId { get; set; }
}
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
this.Id(x => x.Id);
this.DiscriminateSubClassesOnColumn("ProductTypeId");
}
}
public class ProductWeSell : Product, IBusinessObject
{
public const int ProductWeSellTypeId = 1;
}
public class ProductWeSellMap : SubclassMap<ProductWeSell>
{
public ProductWeSellMap()
{
this.DiscriminatorValue(ProductWeSell.ProductWeSellTypeId);
}
}
public class ProductWeDontSell : Product
{
public const int ProductWeDontSellTypeId = 2;
}
public class ProductWeDontSellMap : SubclassMap<ProductWeDontSell>
{
public ProductWeDontSellMap()
{
this.DiscriminatorValue(ProductWeDontSell.ProductWeDontSellTypeId);
}
}
这将产生以下HBM映射:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="CellTester.Test.Database.Product, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" table="`Product`">
<id name="Id" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="guid.comb" />
</id>
<discriminator type="String">
<column name="ProductTypeId" />
</discriminator>
<subclass name="ProductWeSell, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" discriminator-value="1" />
<subclass name="ProductWeDontSell, Test, Version=2.0.0.3, Culture=neutral, PublicKeyToken=a15dc1b99998d28b" discriminator-value="2" />
</class>
</hibernate-mapping>
我得出了有趣的结论。 我决定更改我的体系结构,并为数据访问层和域UI层使用单独的类,我只是在对象穿过层时对其进行转换。 无论如何,将数据访问和UI分离都是一个好习惯。 因此,我的数据访问模型现在非常简单,没有任何继承,继承仅出现在域UI级别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.