概述

自定义医疗储存数据访问层必须包含以下类:

My.Medical.Storage.DataAccessLayer

本教程中使用的医疗存储数据访问层包含以下帮助程序类,这些类并不是严格符合完整的需求的,而是简化版本的实现:

Helper 类 实现My.Medical.Storage.DataAccessLayer
从DicomDataSet对象中提取患者,检验,系列和实例信息,并相应地添加/更新System.Data.DataSet表(患者,检验,系列,实例) class MyDicomDataSetConvertor
用于构建SQL查询语句的SQL查询语句和语句片段 class MyConstants
class MySqlStatments

示例自定义医疗存储数据访问层称为My.Medical.Storage.DataAccessLayer。 它作为示例项目包含在LEAD安装中。 它包含两个表中的所有类。

在Visual Studio中打开项目文件,您将看到项目中的文件:

项目文件

下表介绍了每个文件的内容: 项目文件

这些类在下面进行了详细描述,并按命名空间进行组织:

namespace My.Medical.Storage.DataAccessLayer

  • class MyPatientInfo : IPatientInfo
  • class MyStudyInfo : IStudyInfo
  • class MySeriesInfo : ISeriesInfo
  • class MyInstanceInfo : IInstanceInfo
    • 实现一个接口从System.Data.DataRow中提取DICOM数据
  • class MyStorageDataAccessConfigurationView

    • 用于创建数据访问代理的助手类
    • 内部存储实现IStorageDataAccessAgent(MyStorageSqlDbDataAccessAgent)的类型,因此可以动态创建
    • 将DataAccessLayer与DataAccessAgent和配置文件(GlobalPacs.config)关联起来
    • 定义DataAccessLayer部分名称(在GlobalPacs.config中使用)
    • GlobalPacs.config依次将DataAccessLayer部分名称与连接字符串相关联
  • class MyStorageSqlDbDataAccessAgent

    • 提供创建SQL查询以访问(插入,更新,删除)数据库中的表项的方法
    • 这些方法覆盖StorageSqlDbDataAccessAgent的默认行为。
    • Query Commands

      • protected override void PreparePatientsQueryCommand
      • protected override void PrepareStudiesQueryCommand
      • protected override void PrepareSeriesQueryCommand
      • protected override void PrepareInstanceQueryCommand
      • 根据级别创建一个查询数据库的命令(即PrepareSeriesQueryCommand为系列级数据库查询创建一个命令)
      • 重写PrepareInstancePageQueryCommand
      • 使用分页时准备实例级命令。分页返回一个或多个数据页面的结果,其中用户指定页面大小。此示例数据访问代理中未实现分页功能。
    • Count Commands

      • protected override void PreparePatientsQueryCountCommand
      • protected override void PrepareStudiesQueryCountCommand
      • protected override void PrepareSeriesQueryCountCommand
      • protected override void PrepareInstanceQueryCountCommand
      • 创建一个命令,返回匹配在matchingParamsCollection中指定的搜索条件的行数
    • 删除命令

      • protected override void PrepareDeletePatientsCommand
      • protected override void PrepareDeleteStudiesCommand
      • protected override void PrepareDeleteSeriesCommand
      • protected override void PrepareDeleteInstanceCommand
      • 根据matchingParamsCollection中指定的搜索条件创建删除System.Data.DataTable行的命令
      • protected override void PrepareDeletePatientsNoChildStudiesCommand
      • protected override void PrepareDeleteStudiesNoChildSeriesCommand
      • protected override void PrepareDeleteSeriesNoChildInstancesCommand
      • 创建一个命令,从子表中没有相应行的表中删除行。例如,如果MyPatient表项在MyStudy表中没有对应的条目,则将调用PrepareDeletePatientsNoChildStudiesCommand命令。
      • public override int DeletePatient
      • public override int DeleteStudy
      • public override int DeleteSeries
      • public override int DeleteInstance
      • 根据在matchingParamsCollection中指定的搜索条件从数据库表中删除行的高级命令
      • 使用PrepareDeleteXxxxCommand()覆盖
      • 这些命令还会删除层次结构中上方表格中的相应行
      • 例如,DeleteStudy将从MyStudy表中删除一行或多行。如果相应的MyPatientTable患者行不包含更多研究,那么这些行也会被删除。
    • Exists命令

      • protected override void PrepareIsPatientExistsCommand
      • protected override void PrepareIsStudiesExistsCommand
      • protected override void PrepareIsSeriesExistsCommand
      • protected override void PrepareIsInstanceExistsCommand
      • 根据唯一ID(PatientID,StudyInstanceUID,SeriesInstanceUID或SOPInstanceUID)创建命令以测试存在性。
    • 其他命令

      • 保护覆盖字符串[] GetCompositeInstanceQueryDataAdapterTables
      • 返回包含数据库中所有表名称的列表
      • 保护覆盖DataSet CreateCompositeInstanceDataSet
      • 创建一个表示数据库表的数据集。这实际上是一个强类型,但它作为基类DataSet返回。默认实现返回CompositeInstanceDataSet。对于本教程,您将返回强类型的MyDataSet。

        • MyPatient
        • MyStudy
        • MySeries
        • MYINSTANCE
      • public virtual void UpdateCompositeInstance

        • 根据输入参数myDataSet更新数据库中的必要表项(MyPatient,MyStudy,MySeries,MyInstance)。
        • myDataSet是一个DataSet,包含需要应用的所有必需的添加,更新和删除
        • 如果在此过程中发生异常,则所有更新都将被退出。
      • public override void StoreDicom

        • 为Leadtools.Dicom.DicomDataSet创建必要的表项(MyPatient,MyStudy,MySeries,MyInstance)
        • 基于参数来覆盖表格行
        • updateExistentPatient
        • updateExistentStudy
        • updateExistentSeries
        • updateExistentInstances

namespace My.Medical.Storage.DataAccessLayer.DataAccessLogic.BusinessEntity

class MyDataSet

namespace My.Medical.Storage.DataAccessLayer.DataAccessLogic.DataAccessAgent.Database.SqlServer

  • class MyConstants
  • class MySqlStatments
    • MyStorageSqlDbDataAccessAgent类用于查询/更新/删除数据库中的项的SQL查询语句和语句片段

namespace My.Medical.Storage.DataAccessLayer.DataAccessLogic.DicomDataSetConvertor

  • class MyDicomDataSetConvertor

    • public void FillADONetDataSet
    • 由MyStorageSqlDbDataAccessAgent.StoreDicom调用
    • 从DicomDataSet对象中提取患者,研究,系列和实例信息,并相应地添加/更新DataSet表(患者,研究,系列,实例)。
    • 更新参数(updateExistentPatient,updateExistentStudy,updateExistentSeries,updateExistentInstances)会影响相应的现有DataSet行是保持不变还是被覆盖。
    • 例如,如果updateExistentPatient为true且已有一行具有相同患者ID的DataSet“MyPatient”表,则患者行将被新的患者数据覆盖。
    • public bool AutoTruncate
    • 如果为true,则在必要时截断DicomDataSet中的数据,以便在DataTable列中最大长度。
    • private void FillPatientData
    • 如果DicomDataSet PatientID尚未存在,则向DataSet Patient表(MyPatientTable)添加新行
    • private void FillStudiesData
    • 如果DicomDataSet StudyInstanceUID尚不存在,则向DataSet Study Table(MyStudyTable)添加一个新行
    • private void FillSeriesData
    • 如果DicomDataSet SeriesInstanceUID尚不存在,则向DataSet Study Table(MySeriesTable)添加一个新行
    • private void FillInstancetData
    • 如果DicomDataSet SOPInstanceUID尚不存在,则向DataSet Study Table(MyInstanceTable)添加一个新行
    • oprivate void FillPatientInformation
    • 如果'update'参数为true,则将所有DataSet Patient表信息替换为DicomDataSet中的相应信息。
    • 此方法需要根据您的架构进行更改。 对于教程模式,我们更新患者表中的所有字段

      • PatientName
      • PatientBirthday
      • PatientSex
      • PatientComments
    • private void FillStudyInformation

    • 如果'update'参数为true,则将所有DataSet Study表信息替换为DicomDataSet中的相应信息。
    • 此方法需要根据您的架构进行更改。 对于教程架构,我们更新Study表中的所有字段

      • StudyDate
      • AccessionNumber
      • StudyDescription
      • StudyReferringPhysiciansName
    • private void FillSeriesInformation

    • 如果'update'参数为true,则将所有DataSet Series表信息替换为DicomDataSet中的相应信息。
    • 此方法需要根据您的架构进行更改。 对于教程架构,我们更新Series表中的所有字段

      • SeriesNumber
      • SeriesDate
      • SeriesDescription
      • Modality
      • BodyPartExamined
    • private void FillInstanceInformation

      • 如果'update'参数为true,则将所有DataSet Instance表信息替换为DicomDataSet中的相应信息。
      • 此方法需要根据您的架构进行更改。 对于教程架构,我们更新Series表中的所有字段
      • InstanceNumber
      • SOPClassUID
      • Rows
      • Columns
      • BitsAllocated
      • ImageLastStoreDate - 更新至当前日期.
      • ImageFilename - 存储DicomDataSet的位置的完整路径

namespace My.Medical.Storage.DataAccessLayer.Entities

  • public class MyPatient
  • public class MyStudy
  • public class MySeries
  • public class MyInstance
    • 这些类与MatchingParameterCollection一起使用,以生成数据库查询的WHERE语句。
    • MatchingParameterCollection包含一个MatchingParameterList
    • MatchingParameterList包含一个或多个ICatalogEntity
    • MyPatient,MyStudy,MySeries和MyInstance类均派生自CatalogEntity(实现ICatalogEntity接口)。
    • MyPatient包含可在MyPatientTable中查询的所有内容的属性。
    • 每个属性都使用[EntityElementAttribute]属性进行修饰。
    • 例如,MyPatientTable包含以下列,其中任何一个或全部都可以是查询的一部分
    • PatientId
    • PatientIdentification
    • PatientName
    • PatientBirthday
    • PatientSex
    • PatientComments
    • 可以使用MatchingParameterCollection调用MyStorageSqlDbDataAccessAgent中的任何覆盖
    • 示例:准备一个生成查询的System.Data.IDbCommand或名为'Smith'的所有男性患者

C#代码

// This example builds an IDbCommand

// for querying the MyPatient table

// The generated WHERE clause contains PatientName and PatientSex

public void MyExample()

{

MatchingParameterCollection matchingParamCollection = new
MatchingParameterCollection();

MatchingParameterList matchingParamList = new MatchingParameterList();

MyPatient myPatient = new MyPatient();

myPatient.PatientName = "Smith";

myPatient.PatientSex = "M";

matchingParamList.Add(myPatient);

matchingParamCollection.Add(matchingParamList);

IDbCommand command = new SqlCommand();

// This reads the storage catalog

// Before you run this, make sure and add the following to your application
configuration file

//\<configSections\>

// \<section name="xmlStorageCatalogSettings"
type="Leadtools.Medical.Storage.DataAccessLayer.XmlStorageCatalogSettings,
Leadtools.Medical.Storage.DataAccessLayer" /\>

//\</configSections\>

StorageCatalog myCatalog = new StorageCatalog();

Collection\<CatalogElement[]\> catalogElements =
CatalogDescriptor.GetElementsCollection(matchingParamCollection, myCatalog ,
true);

PreparePatientsQueryCommand(command, catalogElements);

// The 'WHERE' clause of command.CommandText is the following:

// WHERE ( ( MyPatientTable.PatientName LIKE 'Smith' ) AND (
MyPatientTable.PatientSex LIKE 'M' ) )

Console.WriteLine(command.CommandText);

}

了解更多

这是本系列的第六篇文章,本文介绍了LEAD医学存储服务器数据库如何自定义医疗存储数据访问层,我们将在《LEAD医疗存储服务器自定义数据库系列教程 – 强类型DataSet类和XML》系列的第七篇文章中,着重介绍LEAD医用存储服务器数据库的强类型DataSet类和XML Schema。

系列文章