如何在旧数据库中映射表继承?

时间:2011-09-30 22:18:24

标签: nhibernate fluent-nhibernate

我发现映射遗留数据库非常困难。

以下是该方案:承包商申请新许可证。查询并显示许可证。承包商修改需要修改的任何信息。完成后,应用程序将保存到数据库中。

许可属于企业或所有者,这是任何多态关联的一种。许可证本身包含用于建立关联的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);
    }

请告诉我我的映射有什么问题。

1 个答案:

答案 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);
}