Three way join in nhibernate
I am trying to create an NHibernate mapping to the following tables:
AutomatedTestSequence - SequenceID, SequenceName TestStep - StepID, StepDisplay StepSequenceMapping - SequenceID, StepID TestParameters - SequenceID, StepID, ParamID, ParamName, ParamValue
My classes and mapping are as follows:
public class AutomatedTestSequence
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual IList<TestStep> StepsList
{
get;
set;
}
}
and the mapping is:
<class name="AutomatedTestSequence" table="AutomatedTestSequence">
<id name="Id" column="SequenceID"/>
<property name="Name" column="SequenceName"/>
<bag name="TestStep" table="StepSequenceMapping" cascade="none" lazy="false">
<key column ="SequenceID" />
<many-to-many class="TestStep" column="StepID" />
</bag>
</class>
Second class is:
public class TestStep
{
public virtual int Id
{
get;
set;
}
public virtual string Display
{
get;
set;
}
public virtual IList<StepParameter> StepParameterList
{
get;
set;
}
}
and the mapping is:
<class name="TestStep" table="TestStep">
<id name="Id" column="StepID"/>
<property name="Display" column="StepDisplay"/>
<bag name="TestParameters" table="TestParameters" cascade="none" lazy="false">
<key column ="StepID" />
<many-to-many class="TestParameters" column="ParameterId"/>
</bag>
</class>
Third class is:
public class StepParameter
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual string value
{
get;
set;
}
}
and the mapping is:
<class name="TestParameters" table="TestParameters">
<id name="Id" column="ParamID"/>
<property name="Name" column="ParamName" />
<property name="Value" column="ParamValue" />
</class>
My problem is, that the parameter is connected to a specific step in a specific automated test sequence (for example I have a parameter named StartDate
it can have the value 7AM
for step Open Application
in automated sequence Morning Sequence
, and the value 7PM
for step Open Application
in automated sequence Evening Sequence
), but in the current mapping that I have the parameter is connected to the step no matter to which automated test sequence it belongs to. H开发者_运维问答ow do I change my mapping in order to include the automated test sequence id when mapping the parameters?
I'm not sure if this classstructure is fixed. If not consider this:
public class AutomatedTestSequence
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ParameterDictionary> StepParameters { get; set; }
}
public class TestStep
{
public virtual int Id { get; set; }
public virtual string Display { get; set; }
}
public class ParameterDictionary
{
public virtual AutomatedTestSequence Sequence { get; set; }
public virtual TestStep Step { get; set; }
/// <summary>
/// dictionary with paramtername/value pairs
/// </summary>
public virtual IDictionary<string, string> Parameter { get; set; }
public override bool Equals(object obj)
{
var other = obj as ParameterDictionary;
return (other != null) && (Sequence == other.Sequence) && (Step == other.Step);
}
public override int GetHashCode()
{
return Sequence.GetHashCode() ^ Step.GetHashCode();
}
}
class AutomatedTestSequenceMap : ClassMap<AutomatedTestSequence>
{
public AutomatedTestSequenceMap()
{
Id(seq => seq.Id, "AutomatedTestSequence");
Map(seq => seq.Name, "SequenceName");
HasMany(seq => seq.StepParameters)
.Table("StepSequenceMapping")
.KeyColumn("SequenceID");
}
}
class TestStepMap : ClassMap<TestStep>
{
public TestStepMap()
{
Id(step => step.Id, "StepID");
Map(step => step.Display, "StepDisplay");
}
}
class ParameterDictionaryMap : ClassMap<ParameterDictionary>
{
public ParameterDictionaryMap()
{
Table("StepSequenceMapping");
CompositeId()
.KeyReference(spmap => spmap.Sequence, "SequenceID")
.KeyReference(spmap => spmap.Step, "StepID");
HasMany(spmap => spmap.Parameter)
.Table("TestParameters")
.KeyColumns.Add("SequenceID", "StepID")
.AsMap("ParamName")
.Element("ParamValue");
}
}
if you can't or dont want to use FluentNHibernate let me know and i post the xmlmappings.
remarks: ParamID
ist really needed, if it is autogenerated in the database then fine, if set programmaticly then the code above has to be tweaked.
hope this helps
EDIT: the xml mappings
<class mutable="true" name="AutomatedTestSequence" table="`AutomatedTestSequence`">
<id name="Id" type="System.Int32" column="SequenceId">
<generator class="identity" />
</id>
<property name="Name" type="System.String">
<column name="SequenceName" />
</property>
<bag name="StepParameters" table="StepSequenceMapping" mutable="true">
<key>
<column name="SequenceID" />
</key>
<one-to-many class="ParameterDictionary" />
</bag>
</class>
<class mutable="true" name="TestStep" table="`TestStep`">
<id name="Id" type="System.Int32" column="StepID">
<generator class="identity" />
</id>
<property name="Display" type="System.String">
<column name="StepDisplay" />
</property>
</class>
<class mutable="true" name="ParameterDictionary" table="StepSequenceMapping">
<composite-id mapped="false">
<key-many-to-one name="Sequence" class="AutomatedTestSequence" column="SequenceID"/>
<key-many-to-one name="Step" class="TestStep" column="StepID"/>
</composite-id>
<map name="Parameter" table="TestParameters" mutable="true">
<key>
<column name="SequenceID" />
<column name="StepID" />
</key>
<index type="System.String" column="ParamName"/>
<element type="System.String" column="ParamValue"/>
</map>
</class>
精彩评论