J'utilise Fluent NHibernate version 1.0.0.579 (dernière version à cette date). J'ai une classe d'activité abstraite et plusieurs classes héritières, par exemple. DummyActivity. Tous utilisent la même table Activités, et tous ont une valeur de discriminateur basée sur un type intégral qui pointe vers un mappage dans le projet (pas un FK dans la base de données).Fluent NHibernate table par problème de mappage de hiérarchie
Nous avons construit la mise en correspondance comme ceci:
public class ActivityMap : ClassMap<Activity>
{
public ActivityMap()
{
Table("Activities");
Id(x => x.Id).Column("ID").GeneratedBy.Guid();
Map(x => x.ActivityName).Not.Nullable().Length(50);
HasMany(x => x.ActivityParameters)
.KeyColumn("ActivityID")
.AsMap<string>(idx => idx.Column("ParameterName"), elem => elem.Column("ParameterValue"))
.Not.LazyLoad()
.Cascade.Delete()
.Table("ActivityParameters");
DiscriminateSubClassesOnColumn<int>("ActivityType")
.SubClass<DummyActivity>(1, c => { });
}
}
Le fichier généré est hbm.xml:
<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" name="***.Activity, ***, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Activities">
<id name="Id" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ID" />
<generator class="guid" />
</id>
<discriminator column="ActivityType" type="Int32" insert="true" not-null="true" />
<property name="ActivityName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ActivityName" length="50" not-null="true" />
</property>
<map cascade="delete" lazy="false" name="ActivityParameters" table="ActivityParameters">
<key>
<column name="ActivityID" />
</key>
<index type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ParameterName" />
</index>
<element type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ParameterValue" />
</element>
</map>
<subclass name="***.DummyActivity, ***, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1" />
</class>
</hibernate-mapping>
Selon ma conviction, cela ressemble à un fichier hbm.xml valide, identique structure avec l'exemple donné dans le document de référence officiel de NHibernate, à savoir
<class name="IPayment" table="PAYMENT">
<id name="Id" type="Int64" column="PAYMENT_ID">
<generator class="native"/>
</id>
<discriminator column="PAYMENT_TYPE" type="String"/>
<property name="Amount" column="AMOUNT"/>
...
<subclass name="CreditCardPayment" discriminator-value="CREDIT">
...
</subclass>
<subclass name="CashPayment" discriminator-value="CASH">
...
</subclass>
<subclass name="ChequePayment" discriminator-value="CHEQUE">
...
</subclass>
</class>
Faisons-nous une erreur dans notre cartographie? De plus, quelqu'un peut me montrer la nouvelle implémentation recommandée par Fluent (en utilisant SubClass avec colonne discriminante, quelque chose comme
public class ActivityMap : ClassMap<Activity>
{
public ActivityMap()
{
Table("Activities");
Id(x => x.Id).Column("ID").GeneratedBy.Guid();
Map(x => x.ActivityName).Not.Nullable().Length(50);
HasMany(x => x.ActivityParameters)
.KeyColumn("ActivityID")
.AsMap<string>(idx => idx.Column("ParameterName"), elem => elem.Column("ParameterValue"))
.Not.LazyLoad()
.Cascade.Delete()
.Table("ActivityParameters");
DiscriminateSubClassesOnColumn<int>("ActivityType");
}
}
public class DummyActivityMap : SubClass<DummyActivity>
{
///discriminator value here how???
}
?)
La trace de la pile est
[FormatException: Input string was not in a correct format.]
System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +7469351
System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) +119
NHibernate.Type.Int32Type.FromStringValue(String xml) +36
NHibernate.Type.Int32Type.StringToObject(String xml) +10
NHibernate.Persister.Entity.SingleTableEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) +7824
[MappingException: Could not format discriminator value to SQL string of entity ***.Activity]
NHibernate.Persister.Entity.SingleTableEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) +8183
NHibernate.Persister.PersisterFactory.CreateClassPersister(PersistentClass model, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping cfg) +68
NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners) +1468
NHibernate.Cfg.Configuration.BuildSessionFactory() +87
FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH\src\FluentNHibernate\Cfg\FluentConfiguration.cs:93
[FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
]
***.Container.ConfigureNHibernate() in ***.Unity\Container.cs:92
***.Container.ConfigureContainer() in ***.Unity\Container.cs:60
***.Container.GetInstance() in ***.Unity\Container.cs:45
***.Global.CreateContainer() in ***\Global.asax.cs:72
***.Global.Application_Start(Object sender, EventArgs e) in ***\Global.asax.cs:44
Non, je n'ai pas regardé http://code.google.com/p/fluent-nhibernate/issues/detail?id=240, c'est un problème ouvert, et j'ai posé une question Regardez aussi: http://groups.google.com/group/fluent-nhibernate/browse_thread/thread/4d38111df91e72b9 J'utilise l'entier comme une énumération, peut-être que je l'adopterai bientôt – DaeMoohn
Dès que Je vais avoir un concept qui fonctionne, je vais essayer avec une énumération aussi et je vais vous donner un n réponse – DaeMoohn
Votre premier lien est cassé. – Astaar