Я определяю UDT в моей БД MS SQL Server 2012 и использую его в хранимой процедуре в базе данных.Я пытаюсь вызвать мою хранимую процедуру из моей программы на c # и получаю сообщение об ошибке.Вот мой код:
Это определение моего UDT:
CREATE TYPE [dbo].[udt_850File] AS TABLE(
[strInbound850FromPharmacyFilename] [nvarchar](1000) NULL,
[strSenderID_ISA06] [nvarchar](15) NOT NULL,
[strReceiverID_ISA08] [nvarchar](15) NOT NULL,
[strInterchangeControlVersion_ISA12] [nvarchar](5) NOT NULL,
[strInterchangeControlNumber_ISA13] [nvarchar](9) NOT NULL,
[chElementDelimiter] [nchar](1) NOT NULL,
[chComponentElementDelimiter] [nchar](1) NOT NULL,
[chSegmentTerminator] [nchar](1) NOT NULL,
[intTransmissionDate_GS04] [int] NOT NULL,
[strVersionRelease_GS08] [nvarchar](12) NOT NULL,
[strTransSetControl_ST02] [nvarchar](9) NOT NULL,
[strPONumber_BEG03] [nvarchar](22) NOT NULL,
[intPODate_BEG05] [int] NOT NULL,
[strWholesalerAccountNum_N1BY04] [nvarchar](80) NOT NULL,
[dtFileCreatedDateTime] [datetime] NOT NULL
)
Вот мое определение хранимой процедуры:
CREATE PROCEDURE [dbo].[ppisp_sp_850Files_Insert]
@850FileData [dbo].[udt_850File] READONLY
AS
BEGIN
DECLARE @ReturnVal INT = 0
MERGE INTO [dbo].[850Files] AS target
USING @850FileData AS source
ON source.[strInbound850FromPharmacyFilename] = target.[strInbound850FromPharmacyFilename]
AND source.[strSenderID_ISA06] = target.[strSenderID_ISA06]
AND source.[strReceiverID_ISA08] = target.[strReceiverID_ISA08]
AND source.[strInterchangeControlVersion_ISA12] = target.[strInterchangeControlVersion_ISA12]
AND source.[strInterchangeControlNumber_ISA13] = target.[strInterchangeControlNumber_ISA13]
AND source.[chElementDelimiter] = target.[chElementDelimiter]
AND source.[chComponentElementDelimiter] = target.[chComponentElementDelimiter]
AND source.[chSegmentTerminator] = target.[chSegmentTerminator]
AND source.[intTransmissionDate_GS04] = target.[intTransmissionDate_GS04]
AND source.[strVersionRelease_GS08] = target.[strVersionRelease_GS08]
AND source.[strTransSetControl_ST02] = target.[strTransSetControl_ST02]
AND source.[strPONumber_BEG03] = target.[strPONumber_BEG03]
AND source.[intPODate_BEG05] = target.[intPODate_BEG05]
AND source.[strWholesalerAccountNum_N1BY04] = target.[strWholesalerAccountNum_N1BY04]
AND source.[dtFileCreatedDateTime] = target.[dtFileCreatedDateTime]
WHEN NOT MATCHED BY TARGET THEN
INSERT ([strInbound850FromPharmacyFilename]
, [strSenderID_ISA06]
, [strReceiverID_ISA08]
, [strInterchangeControlVersion_ISA12]
, [strInterchangeControlNumber_ISA13]
, [chElementDelimiter]
, [chComponentElementDelimiter]
, [chSegmentTerminator]
, [intTransmissionDate_GS04]
, [strVersionRelease_GS08]
, [strTransSetControl_ST02]
, [strPONumber_BEG03]
, [intPODate_BEG05]
, [strWholesalerAccountNum_N1BY04]
, [dtFileCreatedDateTime])
VALUES (source.[strInbound850FromPharmacyFilename]
, source.[strSenderID_ISA06]
, source.[strReceiverID_ISA08]
, source.[strInterchangeControlVersion_ISA12]
, source.[strInterchangeControlNumber_ISA13]
, source.[chElementDelimiter]
, source.[chComponentElementDelimiter]
, source.[chSegmentTerminator]
, source.[intTransmissionDate_GS04]
, source.[strVersionRelease_GS08]
, source.[strTransSetControl_ST02]
, source.[strPONumber_BEG03]
, source.[intPODate_BEG05]
, source.[strWholesalerAccountNum_N1BY04]
, source.[dtFileCreatedDateTime]);
SET @ReturnVal = @@ROWCOUNT
END
Вот мой файл класса c #, гдеЯ определяю свою таблицу данных и заполняю ее данными:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
namespace PP_ISP_File
{
public class PP_ISP_File_Data
{
public DataTable dt_Files_Info { get; set; }
public PP_ISP_File_Data(string strFileDirectoryPath, int intFileType)
{
dt_Files_Info = new DataTable();
dt_Files_Info.Columns.Add("strSenderID_ISA06", typeof(string));
dt_Files_Info.Columns["strSenderID_ISA06"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strReceiverID_ISA08", typeof(string));
dt_Files_Info.Columns["strReceiverID_ISA08"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strInterchangeControlVersion_ISA12", typeof(string));
dt_Files_Info.Columns["strInterchangeControlVersion_ISA12"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strInterchangeControlNumber_ISA13", typeof(string));
dt_Files_Info.Columns["strInterchangeControlNumber_ISA13"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("chElementDelimiter", typeof(char));
dt_Files_Info.Columns["chElementDelimiter"].DefaultValue = default(char);
dt_Files_Info.Columns.Add("chComponentElementDelimiter", typeof(char));
dt_Files_Info.Columns["chComponentElementDelimiter"].DefaultValue = default(char);
dt_Files_Info.Columns.Add("chSegmentTerminator", typeof(char));
dt_Files_Info.Columns["chSegmentTerminator"].DefaultValue = default(char);
dt_Files_Info.Columns.Add("intTransmissionDate_GS04", typeof(int));
dt_Files_Info.Columns["intTransmissionDate_GS04"].DefaultValue = -1;
dt_Files_Info.Columns.Add("strVersionRelease_GS08", typeof(string));
dt_Files_Info.Columns["strVersionRelease_GS08"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strTransSetControl_ST02", typeof(string));
dt_Files_Info.Columns["strTransSetControl_ST02"].DefaultValue = default(string);
if(intFileType == 850)
{
dt_Files_Info.Columns.Add("strInbound850FromPharmacyFilename", typeof(string));
dt_Files_Info.Columns["strInbound850FromPharmacyFilename"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strPONumber_BEG03", typeof(string));
dt_Files_Info.Columns["strPONumber_BEG03"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("intPODate_BEG05", typeof(int));
dt_Files_Info.Columns["intPODate_BEG05"].DefaultValue = -1;
dt_Files_Info.Columns.Add("strWholesalerAccountNum_N1BY04", typeof(string));
dt_Files_Info.Columns["strWholesalerAccountNum_N1BY04"].DefaultValue = default(string);
}
else if(intFileType == 855)
{
dt_Files_Info.Columns.Add("strOutbound855ToPharmacyFilename", typeof(string));
dt_Files_Info.Columns["strOutbound855ToPharmacyFilename"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("strPONumber_BAK03", typeof(string));
dt_Files_Info.Columns["strPONumber_BAK03"].DefaultValue = default(string);
dt_Files_Info.Columns.Add("intPODate_BAK04", typeof(int));
dt_Files_Info.Columns["intPODate_BAK04"].DefaultValue = -1;
dt_Files_Info.Columns.Add("strWholesalerAccountNum_N1ST04", typeof(string));
dt_Files_Info.Columns["strWholesalerAccountNum_N1ST04"].DefaultValue = default(string);
}
dt_Files_Info.Columns.Add("dtFileCreatedDateTime", typeof(DateTime));
dt_Files_Info.Columns["dtFileCreatedDateTime"].DefaultValue = default(DateTime);
dt_Files_Info = GetFileDetails(strFileDirectoryPath, intFileType);
}
private DataTable GetFileDetails(string strFileDirectoryPath, int intFileType)
{
DataTable dtPP_ISP_Files_Return = dt_Files_Info.Clone();
DirectoryInfo diDirectoryInfo = new DirectoryInfo(strFileDirectoryPath);
if (diDirectoryInfo.Exists)
{
foreach (FileInfo fiFileInfo in diDirectoryInfo.GetFiles())
{
if (fiFileInfo.Exists)
{
using (StreamReader srFile = new StreamReader(fiFileInfo.FullName))
{
string strFileData = System.IO.File.ReadAllText(fiFileInfo.FullName);
if (strFileData.Length >= 104)
{
DataRow dr = dtPP_ISP_Files_Return.NewRow();
char chElementDelimiter = default(char);
char chComponentElementDelimiter = default(char);
char chSegmentTerminator = default(char);
chElementDelimiter = Convert.ToChar(strFileData.Substring(3, 1));
dr["chElementDelimiter"] = chElementDelimiter;
chComponentElementDelimiter = Convert.ToChar(strFileData.Substring(104, 1));
dr["chComponentElementDelimiter"] = chComponentElementDelimiter;
chSegmentTerminator = Convert.ToChar(strFileData.Substring(105, 1));
dr["chSegmentTerminator"] = chSegmentTerminator;
dr["dtFileCreatedDateTime"] = File.GetCreationTime(strFileDirectoryPath);
string[] arrFileLines = strFileData.Split(Convert.ToChar(chSegmentTerminator));
for (int i = 0; i <= arrFileLines.Length - 1; i++)
{
string[] arrLineData = arrFileLines[i].Split(Convert.ToChar(chElementDelimiter));
string strLineQualifier = arrLineData[0].Trim();
switch (strLineQualifier)
{
case "ISA":
dr["strSenderID_ISA06"] = arrLineData[6].Trim();
dr["strReceiverID_ISA08"] = arrLineData[8].Trim();
dr["strInterchangeControlVersion_ISA12"] = arrLineData[12].Trim();
dr["strInterchangeControlNumber_ISA13"] = arrLineData[13].Trim();
break;
case "GS":
dr["intTransmissionDate_GS04"] = Convert.ToInt32(arrLineData[4].Trim());
dr["strVersionRelease_GS08"] = arrLineData[8].Trim();
break;
case "ST":
dr["strTransSetControl_ST02"] = arrLineData[2].Trim();
break;
case "BEG":
dr["strInbound850FromPharmacyFilename"] = fiFileInfo.Name;
dr["strPONumber_BEG03"] = arrLineData[3].Trim();
dr["intPODate_BEG05"] = Convert.ToInt32(arrLineData[5].Trim());
break;
case "BAK":
dr["strOutbound855ToPharmacyFilename"] = fiFileInfo.Name;
dr["strPONumber_BAK03"] = arrLineData[3].Trim();
dr["intPODate_BAK04"] = Convert.ToInt32(arrLineData[4].Trim());
break;
case "N1":
if(arrLineData[1].Trim() == "BY")
{
dr["strWholesalerAccountNum_N1BY04"] = arrLineData[4].Trim();
dtPP_ISP_Files_Return.Rows.Add(dr);
}
else if (arrLineData[1].Trim() == "ST")
{
dr["strWholesalerAccountNum_N1ST04"] = arrLineData[4].Trim();
dtPP_ISP_Files_Return.Rows.Add(dr);
}
break;
default:
break;
}
}
}
}
}
}
}
return dtPP_ISP_Files_Return;
}
}
}
и, наконец, вот мой код, где я инициализирую свою таблицу данных и пытаюсь передать ее хранимой процедуре в моей базе данных:
using (SqlCommand cmd = new SqlCommand(strSPName, con))
{
PP_ISP_File_Data dtFileInfo = new PP_ISP_File_Data(strWatchPath, intFileType);
cmd.CommandText = strSPName;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter spFilenames = new SqlParameter("@850FileData", SqlDbType.Structured);
spFilenames.TypeName = "dbo.udt_850File";
spFilenames.Value = dtFileInfo;
cmd.Parameters.Add(spFilenames);
SqlParameter returnParameter = new SqlParameter("@ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(returnParameter);
con.Open();
cmd.ExecuteNonQuery();
int result = Convert.ToInt16(returnParameter.Value);
}
Запуск моего кода дает мне эту ошибку:
System.InvalidCastException: 'Не удалось преобразовать значение параметра из PP_ISP_File_Data в IEnumerable`1.'
У меня естьесть подозрение, что, поскольку я объявляю свою таблицу данных в файле класса, он не получает что-то, что необходимо для ее перечисления при передаче в хранимую процедуру, но я не знаю, как это исправить.Может кто-нибудь указать мне правильное направление, чтобы это исправить?Заранее спасибо.