c# - 复杂(多架构) Entity Framework 对象映射,用于办公室管理应用程序的无缝集成(并最终替换)

标签 c# sql entity-framework domain-driven-design foxpro

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

首先,一些背景:

我目前在一个很小的专职医师办公室(少于10名员工)中的所有工作都是千篇一律的工作,这使我处于一个独特的职位,在此我可以自由支配(并获得适度的资源支持)来开发和实施任何类型的应用程序/当前系统运行良好,因此没有任何需求或压力的工具。

目前,我们运行的是一个过时的(大约2008年)医疗办公室管理系统,该系统负责处理患者的商业帐户,账单和保险索赔。办公室本身是相当危险的网络。我们有几台使用标准DICOM的诊断机,但大多数病历仍然是纸质的。

我的期望可能超出了我目前的期望,但我计划逐步开发一个功能更广泛,领域驱动的应用程序,将电子病历(评估/管理和DICOM诊断)与医疗办公室管理相结合结束。一旦有了这样一个应用程序的框架,我所处的沙箱环境就会吸引我,我可以探索和开发任何我梦dream以求的自动化或工具。

诚实一点:

我在这类事情上的经验非常有限,但是我是一个非常有决心的人,我喜欢应用程序驱动的学习。

我的问题:

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

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

我能想到这样的事情吗?我一直在测试派生所有fluentAPI映射(.ToTable().HasColumnName()等)的过程,但这是一个相当艰巨的任务,我希望在潜水之前先获得一些更有经验的见解。我找不到任何相关示例,说明有人在尝试我的尝试,这也有些令人沮丧。

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

令人头疼的主要目的是在保持当前应用程序正常运行的同时,还允许我运行和开发新应用程序。

简而言之:

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



编辑1:

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

App X的前身在Unix上运行,也位于FoxPro / xBASE表上,因此App X可能是在此之上构建的,以简化客户升级的过程。 App X目录还包含Visual Fox Pro 6 .dlls和带有FoxPro .ico且名称为“ fbaseeng”的应用程序文件,该文件将弹出标题为“ DTS Command Prompt”的命令提示符窗口。我不确定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
    包含每个法案下的订单项。它是每个继承的表,或者
    费用和过帐/付款的联接,因为它包含由C指示的两个记录,或
    P
    在“类型”列中。似乎没有一个简单的主键,但是Charges
    ChargeID和过帐/付款都有PostID,两者的格式均为BillID+"000N"。至
     但是,排球调整没有ChargeID / PostID。有FK
     的BillID

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

-Patins.dbf
    似乎是一个链接表,但还包含诸如患者保险之类的信息
    策略的ID号。具有患者ID和ICode的FK。

我还希望与其他各种参照表保持一致(例如诊断,推荐医生和CPT代码),但是它们现在的优先级较低。

我还没有完全设计新应用程序的架构,但是我知道它将更加合乎逻辑,因为诸如地址之类的东西将是一种具体的类型,而不管它是与患者还是与保险公司相关联。

为了这个例子,让我们看一下已经存在的Patins.dbf POCO(它是最小的表之一):

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_PatientIDFK_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:作为Person对象,它将存储在SQL模式的继承表中,那么进行映射的最佳方法是什么?只需将.ToTable("Patins")中的InsurancePolicyMap(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,因为您不能将字符串数组映射到数据库列。

但是首先(也是最重要的)要弄清楚需求。完全自由地构建“任何类型的应用程序”听起来不错,但是用户始终牢记一些东西。在您只键入一行代码之前,我将花足够的时间去动脑筋。同意首先要做的事情。然后在用例之后开始构建应用程序用例。让他们测试每个用例。这将使他们有时间习惯于新系统,并逐渐脱离旧系统,并在您进行操作时微调需求。 (简而言之,这是敏捷开发)。

关于c# - 复杂(多架构) Entity Framework 对象映射,用于办公室管理应用程序的无缝集成(并最终替换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19882588/

相关文章:

php - 从表中删除 (*php 变量*) 中的 id 返回错误

c# - Entity Framework 导致超时错误

c# - Entity Framework ,如何投影到列表中

c# - WPF 自定义控件默认数据绑定(bind)

c# - 省略动态属性的类型而不修改类?

c# - EPPlus 生成的 Excel 已损坏

c# - 使用 gmail 发送电子邮件。错误 : The server response was: 5. 5.1 需要身份验证

mysql - 如何在父表中实现 SQL 外键

sql - 如何从 .sql 文件创建多个存储过程

c# - 如何使用 Linqpad 插入具有指定主键的记录?