Question

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?

Était-ce utile?

La solution 2

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);
    }
}

Autres conseils

I don't know anything about the Fluent NHibernate engine but a many-to-many connection is always made with a link-table/object. So I would expect that you would have something like this:

public class SearchTarget : IEntity
{
    public virtual String Name { get; set; }
    public virtual IList<Search_SearchTarget_Link> Searches { get; set; }
}

public class Search : IEntityComponent
{
    public virtual IList<Search_SearchTarget_Link> Targets { get; set; }
}

public class Search_SearchTarget_Link : IEntity
{
    public virtual Search search { get; set; }
    public virtual SearchTarget searchtarget { get; set; }
}

public partial class PoliceAssistance
{
    public virtual Search SearchWithWarrant { get; set; }
    public virtual Search SearchWithoutWarrant { get; set; }
}

Hope this helps...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top