我正在使用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; }
}
}
以下是FluentMappings
public class CountryMap : ClassMap<Country>
{
public CountryMap()
{
Id(x => x.CountryID);
Map(x => x.Name);
Map(x => x.ISOCountryCode);
Map(x => x.InternationalCallingCode);
Table("tblCountry");
}
}
public class CustomerAddressMap : ClassMap<CustomerAddress>
{
public CustomerAddressMap()
{
Id(x => x.CustomerAddressID);
Map(x => x.Street);
Map(x => x.TownOrCity);
Map(x => x.County);
Map(x => x.Postcode);
References(x => x.Country)
//.Not.LazyLoad()
.Cascade.All();
References(x => x.Customer);
//.Not.LazyLoad();
Table("tblCustomerAddress");
}
}
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.CustomerID);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.IsActive);
HasMany(x => x.Addresses)
//.Not.LazyLoad()
.Inverse()
.Cascade.All();
Table("tblCustomer");
}
}
在我的应用程序中,我已经创建了客户,但没有添加任何地址。我创建了一个用于添加/更新客户及其地址的屏幕。
屏幕上有两个用于名字和姓氏的文本框以及一个用于IsActive状态的复选框。还有一个数据网格来添加和更新客户地址。
数据网格有一个组合框列,用于其他字段的国家/地区和文本框列。
我的问题是向已创建的客户添加地址。 (我也不知道如何为新客户添加地址)
在网格中键入地址详细信息并选择国家/地区后,我点击了保存按钮,期望NHibernate将数据保存到相应的表格中,并将新添加的地址链接到当前客户。
当我检查客户对象发送NHibernate进行保存时,它已将地址添加到Addresses IList,但新添加的CustomerAddress实例的Customer属性为NULL。由于我对NHibernate / FluentNHibernate没有太多经验,我认为保存NHibernate会更新Customer for Customer地址。
地址已保存到数据库,但未添加对客户的引用。
但是,当我查看生成的SQL输出时,我看不到任何语句使用正确的客户ID更新新添加的客户地址。相反,它生成并更新用于更新Country的语句,这是不需要的。
下面是NHibernate生成的SQL输出。
NHibernate:
INSERT INTO tblCustomerAddress (Street, TownOrCity, County, Postcode, Country_id, Customer_id)
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
@p0 = 'Street 1' [Type: String (0)], @p1 = 'Town 1' [Type: String (0)], @p2 = 'County 1' [Type: String (0)], @p3 = '123' [Type: String (0)], @p4 = 2 [Type: Int32 (0)], @p5 = NULL [Type: Int32 (0)]
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更新新添加的客户地址。我无法弄清楚我的代码中发生了什么,我不确定我是否正确指定了关系。
如果有人可以帮我解决这个问题,那将是一个很大的帮助。
感谢.....
NHibernate映射一旦使用ExportTo()函数导出。
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>
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>
答案 0 :(得分:0)
您已在客户和客户之间建立了双向参考。 CustomerAddress对象是一件好事。问题可能是将CustomerAddress实例添加到Addresses列表的代码未设置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实例手动分配Customer引用,NHibernate将无法知道在写入数据库时从哪里提取Customer键。如果您正在检索Customer对象,那么NHibernate将自动连接参考分配。