Reputation: 966
I am struggling with mapping subclasses using NHibernate. I am saving reports that we generate and currently there are two different criteria types that I am serializing and would like to store in one column (Criteria) per report: Basic and Time. Every report will have an XML column for criteria that is not null. Here are my classes:
My Report class is the primary class being mapped:
namespace Core {
public class Report {
public virtual int ReportId { get; set; }
public virtual string Name { get; set; }
public virtual ReportCriteria Criteria { get; set; }
}
}
My ReportCriteria class is abstract and inherited by the two criteria types:
namespace Core{
[XmlRoot("Criteria"), Serializable]
public abstract class ReportCriteria {
public abstract string GenSql();
}
}
My BasicCriteria class inherits from ReportCriteria and uses the GenSql() method:
namespace Core {
[XmlRoot("Criteria"), Serializable]
public class BasicCriteria : ReportCriteria {
public override string GenSql(){
//method implementation
}
}
}
My TimeCriteria class inherits from ReportCriteria and uses the GenSql() method:
namespace Core {
[XmlRoot("Criteria"), Serializable]
public class TimeCriteria : ReportCriteria {
[Past]
public virtual DateTime StartDate { get; set; }
public virtual DateTime EndDate { get; set; }
public override string GenSql(){
//method implementation
}
}
}
Finally, my mapping file (Report.hbm.xml) is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping namespace="Core" assembly="Core" xmlns="urn:nhibernate-mapping-2.2">
<class name="Report" table="Report">
<id name="ReportId">
<generator class="identity" />
</id>
<discriminator column="CriteriaType" />
<property name="Name" />
<subclass name="Core.BasicCriteria" discriminator-value="Basic">
<property name="Criteria" type="Data.NHibernate.XmlSerializableType`1[[Core.BasicCriteria, Core]], Data" />
</subclass>
<subclass name="Core.TimeCriteria" discriminator-value="Time">
<property name="Criteria" type="Data.NHibernate.XmlSerializableType`1[[Core.TimeCriteria, Core]], Data" />
</subclass>
</class>
</hibernate-mapping>
Data.NHibernate.XmlSerializableType is a class which accepts generic types and serializes them for data persistence.
Please help me figure out what is wrong with my mapping which is causing the following error to occur: Ex: Exception occurred getter of Core.Report.ReportId Inner: Object does not match target type.
Thanks in advance!
Upvotes: 2
Views: 5537
Reputation: 179
In my case, it was because the condition for retrieving the entity via NH's linq provider included calling IEnumerable's Contains extension method when it was not IQueryable instance. Turning the collection into List by ToList() solved it because ICollection has native support for Contains().
Upvotes: 2
Reputation: 13200
try:
<id name="ReportId" type="Int32">
NHibernate attempts to resolve as string by default so you need to tell it that it is an integer.
Update
Your basic issue is that you are trying to say in your mapping that BasicCriteria and TimeCriteria are subclasses of Report which is not the case. You need to reconsider your mapping strategy. It's been a while since I've done something like this but what you are hinting at (with your criteria columns in the Report table) is a polymorphic component relationship which is not supported. You may want to look a UserTypes
Upvotes: 1