In this tutorial you will customize a database by adding two new columns to tables in an existing database. Then create an Leadtools.Medical.Worklist.DataAccessLayer.IWorklistDataAccessAgent object to query and update the new columns. Finally you will map the new columns to the appropriate DICOM elements for the client query responses.
For a complete working demo program and source code that incorporates the following steps refer to the CustomizingWorklistDAL demo in <InstallationDirectory>\Bin\Dotnet\Win32 and the source code in <InstallationDirectory>\Examples\Dotnet\.
Note: These tasks and code snippets assume that you have created and configured the base Modality Worklist database and a valid connection exists. LEADTOOLS provides Microsoft SQL Server Compact Edition database files for you to use if necessary. The files are named LeadDicomWorklist32.sdf and LeadDicomWorklist64.sdf. They are a 32-bit and 64-bit respectively and are located in C:\Users\Public\Documents. Choose the database that is appropriate for your application and environment
The two new columns to create are a "SmokingStatus" column in the "Patient" table and a "CommentsOnTheScheduledProcedureStep" in the "ScheduledProcedureStep" table. The two new columns will be mapped to the following DICOM elements:
alter table [Patient] add [SmokingStatus]nvarchar(10) alter table [ScheduledProcedureStep] add [CommentOnTheSchedulerProcedureStep] nvarchar(400)
private void QueryWorklistItems () { IWorklistDataAccessAgent agent = GetDataAccessAgent() ; MWLDataset queryResults = agent.QueryModalityWorklists(new MatchingParameterCollection(), new StringCollection()); if (queryResults.Patient.Rows.Count > 0) { queryResults.Patient[0] ["SmokingStatus"] = "UNKNOWN"; } if (queryResults.ScheduledProcedureStep.Rows.Count > 0) { queryResults.ScheduledProcedureStep[0] ["CommentsOnTheScheduledProcedureStep"] = "Some comments on the procedure } agent.UpdateMWL(queryResults); } private IWorklistDataAccessAgent GetDataAccessAgent() { WorklistDataAccessConfigurationView view = new WorklistDataAccessConfigurationView(); IWorklistDataAccessAgent agent; string connectionString = view.GetConnectionStringSettings().ConnectionString; string provider = view.GetConnectionStringSettings().ProviderName; if (provider == DataAccessMapping.DefaultSqlProviderName) { agent = new WorklistSqlDbDataAccessAgent (connectionString); } else if (provider == DataAccessMapping.DefaultSqlCe3_5ProviderName) { agent = new WorklistSqlCeDataAccessAgent(connectionString); } else { throw new NotImplementedException(); } return agent; }
Now that the Leadtools.Medical.Worklist.DataAccessLayer.IWorklistDataAccessAgent object is able to query and update the new columns you created, you need to support these columns in the DICOM C-Find responses. The ModalityWorklistAddIn uses the Leadtools.Dicom.Scp.Command.MWLCFindCommand to map these two columns to the correct DICOM element in the response to a client query.
The Leadtools.Dicom.Scp.Command.MWLCFindCommand has a static property, Leadtools.Dicom.Scp.Command.MWLCFindCommand.DefualtMWLIOD, which returns a stream. The stream is an XML file containing the DICOM Modality Worklist IOD elements and tells the Leadtools.Dicom.Scp.Command.MWLCFindCommand how each element is mapped in the returned QueryModalityWorklists.
using (Stream iodStream = MWLCFindCommand.DefualtMWLIOD) { using (FileStream customIODStream = new FileStream(_iodPath, FileMode.Create)) { int readCount; var buffer = new byte[8192]; while((readCount = iodStream.Read(buffer, 0, buffer.Length)) != 0) { customIODStream.Write(buffer, 0, readCount); } } }
<element tag="(0010,21a0)" tagName="SmokingStatus" vr="CS" minVM="1" maxVM="1" vmDivider="1" returnType="Type3" matchingType="NotApplicable" returning="true" tableName="Patient" matchingEntity="" columnsName="SmokingStatus" />
<element tag="(0040,0400)" tagName="CommentsOnTheScheduledProcedureStep" vr="LT" minVM="1" maxVM="1" vmDivider="1" returnType="Type3" matchingType="NotApplicable" returning="true" tableName="ScheduledProcedureStep" matchingEntity="" columnsName="CommentsOnTheScheduledProcedureStep" />
private static void ValidateDocument(string iodPath) { XmlSchema mwlSchema; XmlReaderSettings settings; mwlSchema = MWLCFindCommand.IODSchema; settings = new XmlReaderSettings(); settings.Schemas.Add(mwlSchema); settings.ValidationType = ValidationType.Schema; settings.ValidationEventHandler += new ValidationEventHandler(schemaValidationHandler); using (XmlReader reader = XmlTextReader.Create(iodPath, settings)) { while (reader.Read()); } } private static void schemaValidationHandler(object sender, ValidationEventArgs args) { throw args.Exception; }
MWLCFindCommand command = new MWLCFindCommand(clientSession, requestDS, GetDataAccessAgent()); AutoResetEvent resetEvent = new AutoResetEvent(false); command.MWLConfiguration.ModalityWorklistIODPath = _iodPath; command.Execute(resetEvent);
The following are notes and descriptions of the attributes in the MWL IOD file:
The following is an explanation of the <element> and <sequence> XML tags:
<element tag="" tagName="" vr="" minVM="" maxVM="" vmDivider="" returnType="" matchingType="" returning="" tableName="" matchingEntity="" columnsName="" /> <sequence tag="" tagName="" vr="SQ" minVM="" maxVM="" vmDivider="" returnType="" returning="" tableName="">