I have the following class tructure.
public class SearchTarget : IEntity {
public virtual String Name { get; set; }
}
public partial class PoliceAssistance {
public virtual Search SearchWithWarrant { get; set; }
public virtual Search SearchWithoutWarrant { get; set; }
public class Search : IEntityComponent {
public virtual IList<SearchTarget> Targets { get; set; }
}
}
IEntityComponent
ensures that PoliceAssistance.Search
is treated as a component in Fluent NHibernate automapping, that is, SearchWithWarrant
and SearchWithoutWarrant
are stored in the same PoliceAssistance
table.
The problem
PoliceAssistance.Search.Targets
and SearchTarget
must have a many-to-many relationship — one search can contain many targets and one target can show up in many searches.
If I specify unidirectional .HasManyToMany()
mapping on PoliceAssistance.Search
, I get a "null value violates non-null constraint" when I try to save the entities — even if both SearchWithWarrant
and SearchWithoutWarrant
are instantiated and have at least one Target
in the list.
If I try to specify the mapping bidirectionally, by introducing public virtual IList<PoliceAssistance.Search> InSearches { get; set; }
property into SearchTarget
and mapping it with .HasManyToMany().Inverse()
, I get a mapping error saying that PoliceAssistance.Search
cannot be referenced because it is not mapped (I guess types mapped as components aren't considered mapped?).
How should I solve this problem?
After fighting with this some more, I gave up on trying to get the mapping working with PoliceAssistance.Search
as component, and instead turned it into a separate entity. This required least amount of changes and works as expected:
// Classes
public class SearchTarget : IEntity {
public virtual String Name { get; set; }
}
public partial class PoliceAssistance {
public virtual Search SearchWithWarrant { get; set; }
public virtual Search SearchWithoutWarrant { get; set; }
public class Search : IEntity {
public virtual int Id { get; set; }
public virtual IList<SearchTarget> Targets { get; set; }
}
}
// Mapping
public class PoliceAssistanceMap : IAutoMappingOverride<PoliceAssistance> {
public void Override(AutoMapping<PoliceAssistance> map) {
map.References(x => x.SearchWithWarrant)
.Cascade.All();
map.References(x => x.SearchWithoutWarrant)
.Cascade.All();
}
}
public class SearchMap : IAutoMappingOverride<PoliceAssistance.Search> {
public void Override(AutoMapping<PoliceAssistance.Search> mapping) {
mapping.HasManyToMany(x => x.Targets);
}
}