NHibernate映射多对多列表没有正确加载对象

时间:2011-09-29 13:55:55

标签: nhibernate nhibernate-mapping

我在我的一个对象中尝试多对多列表。

我有三个类,我试图通过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
    }

我确信这可能是我失踪的小事。有什么想法吗?

1 个答案:

答案 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"进行映射,这不是一个好主意。