我在我的一个对象中尝试多对多列表。
我有三个类,我试图通过NHibernate保存和加载:交叉,车辆和区域。交叉口和车辆均来自设备。
Intersection类包含一个区域列表,每个区域可能只属于1个交叉点,但每个交叉点可能包含多个区域。我正确地映射了它,它正在保存区域的多对一关联到交叉点。
Vehicle类包含区域列表。车辆可以属于多个区域。此外,区域包含车辆清单。每个区域可能包含多个车辆。因此,两者之间的多对多关系。
所有对象似乎都正确保存到数据库中。我可以浏览我的表格,每个交叉路口,车辆和区域的所有字段都正确传播;但是,当我使用NHibernate加载对象时,它们没有加载字段。
我希望有人能够对这里可能出现的问题有所了解。
这是我的Device映射,包括Intersection和Vehicle类映射:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Devices.Device, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Device`" lazy="false">
<id name="PK" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LocalConnection" lazy="false" cascade="all">
<column name="LocalConnection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Connection" lazy="false" cascade="all">
<column name="Connection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Packets.Packet, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Configuration" lazy="false" cascade="all">
<column name="Configuration_id" />
</many-to-one>
<joined-subclass name="EMTRAC.Intersections.Intersection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" lazy="false">
<key>
<column name="Device_id" />
</key>
<component name="Zones" access="property">
<bag name="_list" cascade="all-delete-orphan" access="field" lazy="false" fetch="join">
<key>
<column name="Zone_PK" />
</key>
<many-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>
</component>
<many-to-one class="EMTRAC.Intersections.Streets, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Streets" lazy="false" cascade="all">
<column name="Streets_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Position" lazy="false" cascade="all">
<column name="Position" />
</many-to-one>
</joined-subclass>
<joined-subclass name="EMTRAC.Vehicles.Vehicle, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key>
<column name="Device_id" />
</key>
<component name="Zones" access="property">
<bag name="_list" cascade="all-delete-orphan" access="field" lazy="false" table="VehicleZones" inverse="false">
<key>
<column name="Vehicle_PK" />
</key>
<many-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>
</component>
<property name="Active" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Active" />
</property>
<property name="Status" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Status" />
</property>
<property name="Velocity" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Velocity" />
</property>
<property name="Heading" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Heading" />
</property>
<property name="Agency" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Agency" />
</property>
<property name="Unit" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Unit" />
</property>
<property name="Priority" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Priority" />
</property>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Position" lazy="false" cascade="all">
<column name="Position_id" />
</many-to-one>
<many-to-one class="EMTRAC.VehicleClasses.VehicleClass, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="VehClass" lazy="false" cascade="all">
<column name="VehClass_id" />
</many-to-one>
</joined-subclass>
</class>
</hibernate-mapping>
这是我对Zone类的映射:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Zone`" lazy="false">
<id name="ID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<property name="Active" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Active" />
</property>
<property name="Dir" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Dir" />
</property>
<property name="IntID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="IntID" />
</property>
<property name="Width" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Width" />
</property>
<property name="Distance" type="System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Distance" />
</property>
<many-to-one class="EMTRAC.Headings.Heading, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Heading" cascade="all-delete-orphan">
<column name="Heading_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Start" cascade="all-delete-orphan">
<column name="Start_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Finish" cascade="all-delete-orphan">
<column name="Finish_id" />
</many-to-one>
<component name="Vehicles" access="property">
<bag name="_list" cascade="all-delete-orphan" access="field" lazy="false" table="ZoneVehicles" fetch="join" inverse="true">
<key>
<column name="Zone_PK" />
</key>
<many-to-many class="EMTRAC.Vehicles.Vehicle, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>
</component>
</class>
</hibernate-mapping>
最后这是我的车辆和区域类:
public class Vehicle : Device
{
#region Fields
protected bool active;
protected int id;
protected Position position = new Position();
protected int status;
protected VehicleClass vehClass;
protected int velocity;
protected int heading;
protected string agency;
protected string unit;
protected int priority;
private ZoneCollection zones = new ZoneCollection();
#endregion
#region Properties
[Browsable(false)]
public virtual long PK { get; set; }
[Browsable(false)]
public virtual bool Active
{
get { return active; }
set { active = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("Vehicle Identification Number")]
public virtual int ID
{
get { return id; }
set { id = value; }
}
[Browsable(false)]
public virtual Position Position
{
get { return position; }
set { position = value; }
}
[Browsable(false)]
public virtual int Status
{
get { return status; }
set { status = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("This is the type of vehicle.")]
public virtual VehicleClass VehClass
{
get { return vehClass; }
set { vehClass = value; }
}
[Browsable(false)]
public virtual int Velocity
{
get { return velocity; }
set { velocity = value; }
}
[Browsable(false)]
public virtual int Heading
{
get { return heading; }
set { heading = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("This is the name of the city agency that owns the vehicle.")]
public virtual string Agency
{
get { return agency; }
set { agency = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("This is the ID number assigned to the vehicle by the city or agency and is also used for identification purposes. This field accepts both alpha and numeric entries.")]
public virtual string Unit
{
get { return unit; }
set { unit = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("This is the priority level that the vehicle has over other vehicles with priority control capabilities (1 being the highest, 5 being the lowest). This is not the same as the priority control levels assigned to emergency vehicles (priority 1 for EVP) and mass-transit vehicles (priority 2 for TSP).")]
public virtual int Priority
{
get { return priority; }
set { priority = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("Zones associated with the Vehicle.")]
[System.ComponentModel.Browsable(true)]
[System.ComponentModel.Editor(typeof(VehicleCollectionModalEditor), typeof(System.Drawing.Design.UITypeEditor))]
public virtual ZoneCollection Zones
{
get { return zones; }
set { zones = value; }
}
[Browsable(false)]
public virtual string IPLocal
{
get
{
if (LocalConnection.GetType() == typeof(Connections.ConnectionSerial))
{
return (
((Connections.ConnectionSerial)LocalConnection).SerialConn.PortName + " :: " +
((Connections.ConnectionSerial)LocalConnection).SerialConn.BaudRate.ToString()
);
}
else if (LocalConnection.GetType() == typeof(Connections.ConnectionTCP))
{
return (
((IPEndPoint)((Connections.ConnectionTCP)LocalConnection).Client.Client.RemoteEndPoint).Address.ToString() + " :: " +
((IPEndPoint)((Connections.ConnectionTCP)LocalConnection).Client.Client.RemoteEndPoint).Port.ToString()
);
}
else
{
return string.Empty;
}
}
}
[Browsable(false)]
public virtual string IPNetwork
{
get
{
if (Connection.GetType() == typeof(Connections.ConnectionSerial))
{
return (
((Connections.ConnectionSerial)Connection).SerialConn.PortName + " :: " +
((Connections.ConnectionSerial)Connection).SerialConn.BaudRate.ToString()
);
}
else if (Connection.GetType() == typeof(Connections.ConnectionTCP))
{
return (
((IPEndPoint)((Connections.ConnectionTCP)Connection).Client.Client.RemoteEndPoint).Address.ToString() + " :: " +
((IPEndPoint)((Connections.ConnectionTCP)Connection).Client.Client.RemoteEndPoint).Port.ToString()
);
}
else
{
return string.Empty;
}
}
}
#endregion
}
public class Zone
{
#region Private Fields
private bool active;
private string dir;
private Heading heading = new Heading();
private int id;
private int intID;
private Position start = new Position();
private Position finish = new Position();
private int width;
private Position[] corners = new Position[4];
private Streets streets = new Streets();
private VehicleCollection vehicles = new VehicleCollection();
private double distance;
#endregion
#region Constructors
public Zone()
{
if (Program.main != null)
{
IntID = Program.main.intID;
Intersection intersection = Program.data.Intersections.list.Find(
delegate(Intersection tInt)
{
return tInt.ID == IntID;
}
);
if (intersection != null)
{
Streets.Crossing = intersection.Streets.Crossing;
Streets.Route = intersection.Streets.Route;
}
}
}
#endregion
#region Properties
[Browsable(false)]
public virtual long PK { get; set; }
[Browsable(false)]
public virtual bool Active
{
get { return active; }
set { active = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The direction for the Zone.")]
public virtual string Dir
{
get { return dir; }
set { dir = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("This is the amount of heading variance (clockwise and counter-clockwise) in actual degrees.")]
public virtual Heading Heading
{
get { return heading; }
set { heading = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The Zone Identification Number.")]
public virtual int ID
{
get { return id; }
set { id = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The Identification Number associated with the Priority Detector of the Zone.")]
public virtual int IntID
{
get { return intID; }
set { intID = value; }
}
[CategoryAttribute("Position"),
DescriptionAttribute("The location of the Zone's Start.")]
public virtual Position Start
{
get { return start; }
set { start = value; }
}
[CategoryAttribute("Position"),
DescriptionAttribute("The location of the Zone's Finish.")]
public virtual Position Finish
{
get { return finish; }
set { finish = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The width of the Zone.")]
public virtual int Width
{
get { return width; }
set { width = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The distance of the Zone.")]
public virtual double Distance
{
get { return distance; }
set { distance = value; }
}
[Browsable(false)]
public virtual Position[] Corners
{
get { return corners; }
set { corners = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("The streets associated with the Zone."),
DisplayName("Zone Streets")]
public virtual Streets Streets
{
get { return streets; }
set { streets = value; }
}
[CategoryAttribute("Configuration"),
DescriptionAttribute("Vehicles associated with the Zone.")]
[System.ComponentModel.Browsable(true)]
[System.ComponentModel.Editor(typeof(VehicleCollectionModalEditor), typeof(System.Drawing.Design.UITypeEditor))]
public virtual VehicleCollection Vehicles
{
get { return vehicles; }
set { vehicles = value; }
}
#endregion
}
我确信这可能是我失踪的小事。有什么想法吗?
答案 0 :(得分:1)
1)您的多对多表缺少外键定义。外键将由NH生成,但双方必须相同,因此不起作用。
例如
<many-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="Zone_PK"/>
</many-to-many>
2)行李使用fetch="join"
进行映射,这不是一个好主意。