FluentNHibernate应用程序类关系

FluentNHibernate应用程序类关系,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我在应用程序中使用FluentNHibernate,我在应用程序中遇到了一个问题 下面是班级结构 namespace Project.Core.Models { public class Country { public virtual int CountryID { get; set; } public virtual string Name { get; set; } public virtual string ISOCount

我在应用程序中使用FluentNHibernate,我在应用程序中遇到了一个问题

下面是班级结构

namespace Project.Core.Models
{
    public class Country
    {
        public virtual int CountryID { get; set; }
        public virtual string Name { get; set; }
        public virtual string ISOCountryCode { get; set; }
        public virtual string InternationalCallingCode { get; set; }
    }

    public class CustomerAddress
    {
        public virtual int CustomerAddressID { get; set; }
        public virtual string Street { get; set; }
        public virtual string TownOrCity { get; set; }
        public virtual string County { get; set; }
        public virtual string Postcode { get; set; }
        public virtual Country Country { get; set; }
        public virtual Customer Customer { get; set; }
    }

    public class Customer
    {
        public virtual int CustomerID { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual bool IsActive { get; set; }

        //Customer can have more than one addresses

        public virtual IList<CustomerAddress> Addresses { get; set; }
    }
}
NHibernate:
select@@IDENTITY

NHibernate:

UPDATE tblCountry SET Name = @p0, ISOCountryCode = @p1, InternationalCallingCode = @p2 WHERE CountryID = @p3;
        @p0 = 'United Kingdom' [Type: String (0)], @p1 = 'GBP' [Type: String (0)], @p2 = '+44' [Type: String (0)], @p3 = 2 [Type: Int32 (0)]
没有必要更新国家/地区表,因为这只是我用来获取正确国家/地区的参考表

相反,它应该用正确的customerID更新新添加的客户地址。我不知道代码中发生了什么,也不确定是否正确指定了关系

如果有人能帮我解决这个问题,那将是一个很大的帮助

谢谢

使用ExportTo()函数导出NHibernate映射后

Country.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.Country, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCountry">
    <id name="CountryID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CountryID" />
      <generator class="identity" />
    </id>
    <property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <property name="ISOCountryCode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ISOCountryCode" />
    </property>
    <property name="InternationalCallingCode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="InternationalCallingCode" />
    </property>
  </class>
</hibernate-mapping>

Customer.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.Customer, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCustomer">
    <id name="CustomerID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CustomerID" />
      <generator class="identity" />
    </id>
    <bag cascade="all" inverse="true" name="Addresses">
      <key>
        <column name="Customer_id" />
      </key>
      <one-to-many class="Project.Core.Models.CustomerAddress, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <property name="FirstName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="FirstName" />
    </property>
    <property name="LastName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="LastName" />
    </property>
    <property name="IsActive" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="IsActive" />
    </property>
  </class>
</hibernate-mapping>

CustomerAddress.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.CustomerAddress, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCustomerAddress">
    <id name="CustomerAddressID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CustomerAddressID" />
      <generator class="identity" />
    </id>
    <property name="Street" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Street" />
    </property>
    <property name="TownOrCity" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="TownOrCity" />
    </property>
    <property name="County" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="County" />
    </property>
    <property name="Postcode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Postcode" />
    </property>
    <many-to-one class="Project.Core.Models.Country, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Country">
      <column name="Country_id" />
    </many-to-one>
    <many-to-one cascade="all" class="Project.Core.Models.Customer, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer">
      <column name="Customer_id" />
    </many-to-one>
  </class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.CustomerAddress, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCustomerAddress">
    <id name="CustomerAddressID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CustomerAddressID" />
      <generator class="identity" />
    </id>
    <property name="Street" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Street" />
    </property>
    <property name="TownOrCity" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="TownOrCity" />
    </property>
    <property name="County" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="County" />
    </property>
    <property name="Postcode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Postcode" />
    </property>
    <many-to-one class="Project.Core.Models.Country, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Country">
      <column name="Country_id" />
    </many-to-one>
    <many-to-one cascade="all" class="Project.Core.Models.Customer, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer">
      <column name="Customer_id" />
    </many-to-one>
  </class>
</hibernate-mapping>

CustomerAddress.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.CustomerAddress, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCustomerAddress">
    <id name="CustomerAddressID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CustomerAddressID" />
      <generator class="identity" />
    </id>
    <property name="Street" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Street" />
    </property>
    <property name="TownOrCity" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="TownOrCity" />
    </property>
    <property name="County" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="County" />
    </property>
    <property name="Postcode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Postcode" />
    </property>
    <many-to-one class="Project.Core.Models.Country, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Country">
      <column name="Country_id" />
    </many-to-one>
    <many-to-one cascade="all" class="Project.Core.Models.Customer, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer">
      <column name="Customer_id" />
    </many-to-one>
  </class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Project.Core.Models.CustomerAddress, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="tblCustomerAddress">
    <id name="CustomerAddressID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CustomerAddressID" />
      <generator class="identity" />
    </id>
    <property name="Street" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Street" />
    </property>
    <property name="TownOrCity" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="TownOrCity" />
    </property>
    <property name="County" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="County" />
    </property>
    <property name="Postcode" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Postcode" />
    </property>
    <many-to-one class="Project.Core.Models.Country, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Country">
      <column name="Country_id" />
    </many-to-one>
    <many-to-one cascade="all" class="Project.Core.Models.Customer, Project.Core.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer">
      <column name="Customer_id" />
    </many-to-one>
  </class>
</hibernate-mapping>

您已经在Customer和CustomerAddress对象之间设置了一个双向引用,这是一件好事。问题可能是将CustomerAddress实例添加到地址列表的代码没有设置CustomerAddress.Customer属性。以下是添加新地址时的代码片段:

  // appropriate creating/retrieving of a customer instance has happened...

  //Add a new address:
  var newAddr = new CustomerAddress();

  //Initialize property values as needed:
  newAddr.Street = "some value";
  newAddr.TownOrCity = "some other value";

  //Assign the parent instance to the References property:
  newAddr.Customer = customer;

  customer.Addresses.Add(newAddr);
  //rest of code....

如果您没有手动为新CustomerAddress实例分配客户引用,那么在写入数据库时,NHibernate将不知道从何处提取客户密钥。如果您正在检索客户对象,则NHibernate将自动连接参考分配。

找到了通过对国家/地区表进行不必要的更新来消除问题的方法。删除了.Cascade.All();来自CustomerAddressMap。仍然没有更新客户地址表中的customerid。请在构建配置并将HBM映射发布到某个位置时运行
ExportTo
?将HBM映射文件添加到原始问题中