2

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

首先,一些背景:

我目前在一个极小(<10 名员工)专科医生办公室工作,有点多才多艺,这让我处于一个独特的位置,我可以自由支配(和适度的资源支持)来开发和实施任何类型的应用程序/工具没有任何需求或压力,因为当前系统运行良好。

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

我的愿望可能超出了我目前所能咀嚼的范围,但我计划慢慢开发一个更全面、由领域驱动的应用程序,将电子病历(评估/管理和 DICOM 诊断)与医疗办公室管理相结合结尾。一旦我建立了这样一个应用程序的框架,我所处的沙箱方面就会吸引我,因为我可以探索和开发任何我能梦想到的自动化或工具。

一些诚实:

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

我的问题:

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

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

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

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

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

简而言之:

是否可以使用 EF 将新的 OOR/域驱动的应用程序与模式略有不同的旧数据库集成?如果是这样,有什么提示或示例可以帮助我入门吗?如果没有,我还有其他功能相似的替代品吗?谢谢


编辑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”。

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

- Charges.dbf 包含属于每个账单的行项目。它要么是每个继承的表,要么是费用和过帐/付款的连接,因为它包含由类型列指示CP 在类型列中指示的两个记录。似乎没有一个简单的主键,但是Chargeshave ChargeID和 Postings/Payments have PostID,两者都有 format BillID+"000N"。但是,要投掷曲线球,无效调整没有ChargeID/ PostID。具有BillID.

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

- Patins.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 表的方法时,我的问题终于出现了。具体来看Guarantor:作为一个Person对象,它将存储在 SQL 模式中的继承表中,那么进行映射的最佳方法是什么?简单地.ToTable("Patins")InsurancePolicyMapwith 中(t => t.Guarantor.FirstName).HasColumnName("Guarfname")似乎是合乎逻辑的,但是 EF 会自动处理单独的关系模式吗?Person.FirstName可能更好的措辞:在物理、SQLMap、InsurancePolicy.Guarantor.FirstNameVFPmap 和物理之间的关系/继承中导航是否有问题Patins.Guarfname

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

4

1 回答 1

0

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

您绝对应该规范化数据模型。创建表,例如Insclass使用外键Accttype等等。还有一个Benefit带有 FK 的表,InsurancePolicy因为您无法将字符串数组映射到数据库列。

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

于 2013-11-10T21:37:53.523 回答