我发现映射遗留数据库非常困难。
以下是该方案:承包商申请新许可证。查询并显示许可证。承包商修改需要修改的任何信息。完成后,应用程序将保存到数据库中。
许可属于企业或所有者,这是任何多态关联的一种。许可证本身包含用于建立关联的TableID和RecordID。
许可证包含许多应用程序。此系统中有几种类型的应用程序,因此有一个“ApplicationCommon”表和一个“LicenseApplication”表。此特定应用程序是许可证。 ApplicationCommon和LicenseApplication共享相同的主键。换句话说,ApplicationCommon id与LicenseApplication id相同。所以这是表继承(或者我认为)。
由于与业务的奇怪多态关联,我必须从许可证中分别查询业务数据(或者我认为,nHibernate的新特性)。获得许可证和业务后,我尝试创建一个新的应用程序,即系统出现故障时。
以下是我得到的例外情况:
"object references an unsaved transient instance - save the transient instance
before flushing. Type: LicenseApplication, Entity: LicenseApplication"
以下是映射:
public LicenseApplicationMap()
{
Table("Applications_LicenseApplication");
Id(x => x.ID).Column("intApplicationID").Not.Nullable();
Map(x => x.TableID).Column("intTableID").Nullable();
Map(x => x.RecordID).Column("intRecordID").Nullable();
References(x => x.Type).Column("intLicenseTypeID").Not.Nullable();
Map(x => x.InsuranceExpiresOn).Column("dtInsuranceExpiresOn");
Map(x => x.WCInsuranceExpiresOn).Column("dtWCInsuranceExpiresOn");
Map(x => x.Updated).Column("dtUpdated");
Map(x => x.AuthorizedRepresentativeFirstName).Column("strAuthRepFirstName");
Map(x => x.AuthorizedRepresentativeLastName).Column("strAuthRepLastName");
Map(x => x.AuthorizedRepresentativeGreeting).Column("strAuthRepGreeting");
HasOne(x => x.ApplicationCommon).ForeignKey("intApplicationID").Cascade.All();
References(x => x.License).Column("intLicenseID");
HasMany(x => x.Officers).KeyColumn("intApplicationID");
HasMany(x => x.Designees).KeyColumn("intApplicationID");
}
public LicenseCommonMap()
{
Table("Licensing_LicenseCommon");
Id(x => x.ID).Column("intLicenseID").Not.Nullable();
Map(x => x.TableID).Column("intTableID").Nullable();
Map(x => x.RecordID).Column("intRecordID").Nullable();
Map(x => x.LicenseNumber).Column("strNumber");
References(x => x.Type).Column("intLicenseTypeID").Not.Nullable();
References(x => x.Status).Column("intLicenseStatusID").Not.Nullable();
Map(x => x.StartsOn).Column("dtStartsOn");
Map(x => x.EndsOn).Column("dtEndsOn");
Map(x => x.CreatedOn).Column("dtCreatedOn");
Map(x => x.RenewedOn).Column("dtRenewedOn");
Map(x => x.InsuranceExpiresOn).Column("dtInsuranceExpiresOn");
Map(x => x.WorkmansCompensationExpiresOn).Column("dtWCInsuranceExpiresOn");
Map(x => x.LastUpdated).Column("dtLastUpdated");
HasMany(x => x.Applications).KeyColumn("intLicenseID");
}
public ApplicationCommonMap()
{
Table("Applications_ApplicationCommon");
Id(x => x.ID).Column("intApplicationID");
References(x => x.Type).Column("intApplicationTypeID");
References(x => x.Status).Column("intApplicationStatusID");
References(x => x.LicenseApplication).Column("intApplicationID").Cascade.All();
}
public BusinessMap()
{
Table("Core_Business");
Id(x => x.ID).Column("intBusinessID").GeneratedBy.Identity();
Map(x => x.BusinessName).Column("strBusinessName").Not.Nullable();
Map(x => x.PhoneNumber).Column("strPhoneNumber").Not.Nullable();
Map(x => x.FaxNumber).Column("strFaxNumber").Not.Nullable();
Map(x => x.EmailAddress).Column("strEmailAddress").Not.Nullable();
Map(x => x.YearOrganized).Column("strYearOrganized").Not.Nullable();
Map(x => x.LastUpdated).Column("dtLastUpdated").Not.Nullable();
Map(x => x.PhysicalAddr1).Column("strPhysicalAddr1").Not.Nullable();
Map(x => x.PhysicalAddr2).Column("strPhysicalAddr2").Nullable();
Map(x => x.PhysicalCity).Column("strPhysicalCity").Not.Nullable();
Map(x => x.PhysicalState).Column("strPhysicalState").Not.Nullable();
Map(x => x.PhysicalCountry).Column("strPhysicalCountry").Not.Nullable();
Map(x => x.PhysicalZip).Column("strPhysicalZip").Not.Nullable();
Map(x => x.MailingAddr1).Column("strMailingAddr1").Not.Nullable();
Map(x => x.MailingAddr2).Column("strMailingAddr2").Nullable();
Map(x => x.MailingCity).Column("strMailingCity").Not.Nullable();
Map(x => x.MailingState).Column("strMailingState").Not.Nullable();
Map(x => x.MailingCountry).Column("strMailingCountry").Not.Nullable();
Map(x => x.MailingZip).Column("strMailingZip").Not.Nullable();
}
最后,我使用的是.Net MVC,AutoMapper和S#rpArch,所以这是我的控制器动作和我的查询。 SaveLicense和SaveQuery打扰执行相同的逻辑,SaveOrUpdate,然后刷新。
[HttpPost]
[Transaction]
public ActionResult Edit(int id, LicenseViewModel applicationData)
{
// 1. Get the current license.
var license = _licenseService.GetLicenseCommon(id);
// 2. Make changes to license that where made during application process
Mapper.Map<LicenseViewModel , LicenseCommon>(applicationData, license);
var business = _licenseService.GetBusiness(license.RecordID);
Mapper.Map<LicenseViewModel , Business>(applicationData, business);
business.LastUpdated = DateTime.Now;
// 3. Create a new application and add it to the license
var application = new LicenseApplication();
Mapper.Map<LicenseViewModel , LicenseApplication>(applicationData, application);
application.Updated = DateTime.Now;
application.InsuranceExpiresOn = DateTime.Parse(applicationData.GeneralLiabilityExpiration);
application.WCInsuranceExpiresOn = DateTime.Parse(applicationData.WorkmansCompensationExpiration);
application.TableID = 33;
application.RecordID = license.RecordID;
// 4. Save the license and it's applications to the database.
license.Business = business; //Don't think this works at all...
license.Applications.Add(application);
application.License = license;
///////////////// BOOM THIS IS WHERE IT BLOWS UP //////////////////////
_licenseService.SaveLicense(license);
_businessService.SaveBusiness(business);
// 5. Convert the modified license and it's newly created application to an LicenseViewModel
Mapper.Map<LicenseCommon, LicenseViewModel >(license, applicationData);
// 6. return json or error message
return Json(applicationData);
}
请告诉我我的映射有什么问题。
答案 0 :(得分:0)
HasMany(x => x.Applications).KeyColumn("intLicenseID");
缺少.Cascade.All()
,因此保存许可证也会保存对应用程序的更改。
并且.Inverse
也很好告诉NH应用程序负责该关联。
还
// class LicenseCommon
public void Add(LicenseApplication application)
{
application.License = license;
application.TableID = 33;
application.RecordID = license.RecordID;
Applications.Add(application);
}