用于办公管理应用程序无缝集成(和最终替换)的复杂(多模式)实体框架对象映射

2024-02-27

我是一个相当新手、狂热的程序员。这是我的第一个问题,但几个月来我一直在使用 stackoverflow 来获取有价值的信息。

首先,一些背景:

我目前在一家极小(

我们目前运行一个相当过时(大约 2008 年)的医疗办公室管理系统,负责处理患者业务账户、计费和保险索赔提交。办公室本身是相当偶然的网络化的。我们有几台使用标准 DICOM 的诊断机器,但大多数医疗记录仍然是纸质的。

我目前的愿望可能超出了我目前的承受能力,但我计划慢慢开发一个更全面、领域驱动的应用程序,将电子病历(评估/管理和 DICOM 诊断)与医疗办公室管理结合起来结尾。一旦我奠定了这样一个应用程序的框架,我的情况的沙箱方面就会吸引我,因为我可以探索和开发我能梦想的任何类型的自动化或工具。

一些诚实:

我在这些方面的经验非常有限,但我是一个非常坚定的人,我喜欢应用驱动的学习。

我的问题:

我正在努力首先与当前的患者账户数据库集成。

当前所有内容都存储在 FoxPro 2.5 可用表中。表之间的关系不能隐式获得,但隐含了相当多的关系。理想情况下,我希望将带有 POCO 的新应用程序通过 EF 映射到 SQL 数据库。这部分很简单,但我还希望在单独的 DBContext 中将相同的 POCO 映射到当前的 FoxPro 2.5 .dbfs(不一定具有相同的架构)。

这样的事情有可能像我想象的那样吗?我一直在测试派生所有 FluentAPI 映射的水域(.ToTable(), .HasColumnName()等),但这是一项相当艰巨的任务,在开始之前我希望获得一些更有经验的见解。我一直无法找到任何人实现我正在尝试的事情的相关例子,这也有点令人沮丧。

也许我的做法是错误的。我愿意进行相应的调整,但我喜欢在我的应用程序中使用 POCO 的想法,并且对于我的新应用程序来说,能够与旧数据库通信而不实现其不直观的模式非常重要。

所有令人头疼的问题的关键目的是保持当前应用程序的功能齐全,同时允许我运行和开发我的新应用程序。

简而言之:

是否可以使用 EF 将新的 OOR/域驱动应用程序与架构略有不同的旧数据库集成?如果是这样,有什么建议或例子可以帮助我开始吗?如果没有,我还有其他功能相似的替代方案吗?谢谢


Edit 1:

从现在开始,我将把当前使用的应用程序称为 App X。

App X 的前身在 Unix 上运行,并且也运行在 FoxPro/xBASE 表上,因此 App X 是在此基础上构建的,大概是为了简化客户升级。 App X 目录还包含 Visual Fox Pro 6 .dll 和一个带有 FoxPro .ico 且名称为“fbaseeng”的应用程序文件,该文件将打开一个标题为“DTS 命令提示符”的命令提示符窗口。我不确定 App X 是如何运作的,但“DTS”对我来说很突出,我花了一些时间看看是否有一种方法可以使用他们已经实现的任何数据转换,但我最终放弃了。

当前数据库是一个集合231 .dbf表。幸运的是,其中很大一部分似乎要么完全未使用,要么仅以某种迂回的临时方式使用,即它们不在 App X 运行时之外存储记录。

其中几个表似乎是链接表,其中另一部分包含参考数据,例如类型限定符属性

public partial class Accttype
{
    public decimal Acct_Type { get; set; }
    public string Acct_Desc { get; set; }
    public string Sb { get; set; }
    public decimal Fee { get; set; }
    public bool Acptasgn { get; set; }
    public decimal Insclass1 { get; set; }
    public decimal Insclass2 { get; set; }
    public decimal Insclass3 { get; set; }
    public decimal Insclass4 { get; set; }
    public decimal Insclass5 { get; set; }
    public string Acct_Grp { get; set; }
}

以及邮政编码等静态参考值

public partial class Zip
{
    public string Zipcode { get; set; }
    public string City { get; set; }
    public string St { get; set; }
    public string Areacode { get; set; }
    public decimal Ext_From { get; set; }
    public decimal Ext_To { get; set; }
}

到目前为止,我最关心的是以下表格:

- Patdemo.dbf包含所有患者就诊的记录。它有大约100个 列并包含大量信息,包括姓名、地址、保险 类型、流水账户余额总计等。简单的主键是 患者 ID,但格式为“0.0”。

- 帐单.dbf包含与特定日期的患者相关的字母数字 ID 索引账单 服务。有大约 80 列,主要包括外键/类型限定符和状态 指标(即INS1_SENT)。具有患者 ID 的 FK

- 费用.dbf包含属于每个法案的行项目。它要么是每个继承的一个表,要么是 费用和过帐/付款的合并,因为它包含由C或者P在类型列中。似乎没有一个简单的主键,但是ChargesChargeID和过帐/付款有PostID,都带有格式BillID+"000N"。到 然而,投掷曲线球时,排空调整没有ChargeID/PostID。有FK 的BillID.

- 保险.dbf包含保险提供商以及从地址到电子账单 ID 的信息。 主键是字母数字 ICode(示例:BC01)。

- 帕廷斯.dbf似乎是一个链接表,但也包含患者保险等信息 保单的 ID 号。具有患者 ID 的 FK 和ICode.

我希望与其他各种参考表保持并发(例如诊断、转诊医生和 CPT 代码),但它们现在的优先级较低。

我还没有完全设计我的新应用程序的架构,但我确实知道它会更加合乎逻辑,因为像地址这样的东西将是一个具体类型,无论是否与患者或保险公司相关。

为了这个例子,让我们看一下预先存在的Patins.dbfPOCO(它是最小的表之一):

public partial class Patins
{
    public decimal Custid { get; set; }
    public decimal Inskey { get; set; }
    public string Insurcode { get; set; }
    public string Insurnum { get; set; }
    public string Groupnum { get; set; }
    public string Guarlname { get; set; }
    public string Guarfname { get; set; }
    public string Guarmi { get; set; }
    public string Guargen { get; set; }
    public string Guaraddr { get; set; }
    public string Guaraddr2 { get; set; }
    public string Guarcity { get; set; }
    public string Guarst { get; set; }
    public string Guarzip { get; set; }
    public string Guarcountr { get; set; }
    public string Guarphone { get; set; }
    public string Guaremail { get; set; }
    public System.DateTime Guardob { get; set; }
    public string Guarsex { get; set; }
    public string Guaremp { get; set; }
    public decimal Relation { get; set; }
    public System.DateTime Startdate { get; set; }
    public System.DateTime Enddate { get; set; }
    public bool Active { get; set; }
    public string Bcpc { get; set; }
    public string Auth1 { get; set; }
    public string Auth2 { get; set; }
    public string Auth3 { get; set; }
    public decimal Billcnt { get; set; }
    public string Desc1 { get; set; }
    public string Desc2 { get; set; }
    public string Desc3 { get; set; }
    public decimal Visits1 { get; set; }
    public decimal Visits2 { get; set; }
    public decimal Visits3 { get; set; }
    public System.DateTime From1 { get; set; }
    public System.DateTime From2 { get; set; }
    public System.DateTime From3 { get; set; }
    public System.DateTime To1 { get; set; }
    public System.DateTime To2 { get; set; }
    public System.DateTime To3 { get; set; }
    public string Insnote { get; set; }
    public string Char1 { get; set; }
    public string Char2 { get; set; }
    public string Char3 { get; set; }
    public string Char4 { get; set; }
    public string Char5 { get; set; }
    public string Char6 { get; set; }
    public string Char7 { get; set; }
    public string Char8 { get; set; }
    public string Char9 { get; set; }
    public string Char10 { get; set; }
    public System.DateTime Date1 { get; set; }
    public System.DateTime Date2 { get; set; }
    public decimal Num1 { get; set; }
    public decimal Num2 { get; set; }
    public string Createby { get; set; }
    public System.DateTime Createdt { get; set; }
    public string Modifyby { get; set; }
    public System.DateTime Modifydt { get; set; }
    public string Cobmemo { get; set; }
    public System.DateTime Dinju { get; set; }
    public System.DateTime Dsimbd { get; set; }
    public System.DateTime Dsimed { get; set; }
    public string Createtm { get; set; }
    public string Modifytm { get; set; }
    public bool Archive { get; set; }
    public bool Delflag { get; set; }
    public decimal Coinsded { get; set; }
    public decimal Outpoc { get; set; }
    public System.DateTime Lastupd { get; set; }
    public decimal Coins { get; set; }
    public decimal Msp { get; set; }
}

在现实世界中,患者通过保险单与保险公司相关联。有一个FK_PatientID, FK_InsuranceCarrierID,和唯一的ID,PK_PolicyNumber(可能是 PolicyNumber+InsuranceCarrierID 才安全?)。保单包含规定付款的福利信息,配偶/家庭可以共享保单(通常在保单编号后附加 -0n)。

我可能会让Patient对象包含保险单对象的集合。沿着这些思路:

class Patient : Person
{
    int PatientID { get; set; }
    virtual IEnumerable<InsurancePolicy> InsurancePolicies { get; set; }
}

class InsurancePolicy
{
    int PatientID { get; set; }
    string PolicyNumber { get; set; }
    string GroupNumber { get; set; }
    bool IsActive { get; set; }
    DateTime startDate { get; set; }
    DateTime endDate { get; set; }
    int InsuranceCarrierID { get; set; }
    virtual Person Guarantor { get; set; } //all guarantor information accessible via person aggregate root i.e: Guarantor.FirstName
    string GuarantorRelation { get; set; }
    string[] Benefits { get; set; }  //delineated set of benefit descriptions... automatically parse from EDI benefits message?... seperate value object class?... could contain copay/deduc/OoP
    decimal Deductible { get; set; }
    decimal Copay { get; set; }
    decimal OutofPocket { get; set; }
    virtual IEnumerable<Bill> AssociatedBills { get; set; } //all bills associated with policy... could also be InsuranceClaim objects... Automapper Bill->Claim?
}

还有一些其他事情需要在 InsurancePolicy 或其他地方表示,例如工资百分比,但我现在暂时不考虑它们。

当我寻找将数据映射到旧 FP 表或从旧 FP 表映射数据的方法时,我的问题终于出现了。具体看Guarantor: as a Person对象,它将存储在 SQL 模式的继承表中,那么进行映射的最佳方法是什么?简单地.ToTable("Patins") in the InsurancePolicyMap with (t => t.Guarantor.FirstName).HasColumnName("Guarfname")看起来很合乎逻辑,但是 EF 会自动处理单独的关系模式吗?可能更好的措辞:在处理物理之间的关系/继承方面是否存在困难?Person.FirstName、SQLMap、InsurancePolicy.Guarantor.FirstName、VFPmap 和物理Patins.Guarfname?

关于什么Billcnt?幸运的是,无论出于何种原因,它都没有在 App X 中实现,但是我假设的映射是什么AssociatedBills.Count()?您是否只检查从 FP 表中提取值的有效性?


既然你有“自由统治”,我会借此机会升级整个系统。这是一个非常非常糟糕的数据模型,再拖下去这个遗产确实没有任何用处。这些不伦不类的重复编号字段将成为混乱和错误的持续来源。并且几乎不可能从中建立一个像样的域名。实体框架有很多选项可以以不同于数据模型的方式塑造类模型,但这太多了。实际上,在保留数据模型的同时重建应用程序是没有用的。

你绝对应该正常化数据模型。创建像这样的表Insclass用外键Accttype等等等等。也Benefit带有 FK 的表InsurancePolicy因为您无法将字符串数组映射到数据库列。

但首先(也是最重要的)要明确要求。拥有完全的自由来构建“任何类型的应用程序”听起来不错,但用户总是有一些想法。在你输入一行代码之前,我会花足够的时间来了解他们的想法。首先就要做的事情达成一致。然后开始在用例之后构建应用程序用例。并让他们测试每个用例。这将使他们有时间适应新系统并慢慢脱离旧系统,并随时调整需求。 (简而言之,这就是敏捷开发)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于办公管理应用程序无缝集成(和最终替换)的复杂(多模式)实体框架对象映射 的相关文章

随机推荐