将两个表合并到sql server中的一个表中

时间:2018-01-09 08:43:58

标签: c# sql json sql-server database-schema

我有这些架构:

CREATE TABLE Ndc
(
    [NdcId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [Code] VARCHAR(256) NULL,
)

CREATE TABLE [RxCui]
(
    [RxCuiId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [Code] VARCHAR(256) NULL, 
)

CREATE TABLE [RxCuiNdc]
(
    [RxCuiNdcId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [RxCuiId] INT NOT NULL, 
    [NdcId] INT NOT NULL,
    CONSTRAINT [FK_RxCuiNdc_Ndc] FOREIGN KEY (NdcId) REFERENCES Common.Ndc(NdcId), 
    CONSTRAINT [FK_RxCuiNdc_RxCui] FOREIGN KEY (RxCuiId) REFERENCES Common.RxCui(RxCuiId), 
)

我有一个JSON,它是一个药物标签列表,每个标签都与两个字符串数组相关联。一个数组表示RxCui列表,另一个数组表示Ndc列表。我将获取JSON文件,并将每个RxCui插入到RxCui表中,并将Ndc表中的每个Ndc插入上面的模式中。假设表中包含所有Ndc和RxCui并且没有任何重复项,那么我想将它们映射到RxCuiNdc表。

这是代表JSON的类

public class DrugLabel
    {
        public OpenFda openfda { get; set; }
    }

public class OpenFda
    {
        public IList<string> product_ndc { get; set; } = new List<string>();
        public IList<string> rxcui { get; set; } = new List<string>();
    }

public class DrugLabels
    {
        public List<DrugLabel> results { get; set; } = new List<DrugLabel>();
    }

我尝试了一个存储过程来创建RxCui和Ndc之间的映射。

CREATE PROCEDURE MapRxCuiToNdc
    @rxCuiList varchar(MAX),
    @ndcList varchar(MAX)
AS
    DECLARE @rxCuiTable TABLE (RxCuiCode varchar(max)) 

    -- Insert statement
    INSERT INTO @rxCuiTable
    SELECT Value
    FROM  string_split(@rxCuiList, ',')  

    DECLARE @ndcTable TABLE (NdcCode varchar(max)) 

    -- Insert statement
    INSERT INTO @ndcTable
    SELECT Value
    FROM  string_split(@ndcList, ',')  

    MERGE INTO [Common].[RxCuiNdc] T
       USING (SELECT A.RxCuiId, A.Code AS RxCuiCode, B.NdcId, B.Code AS NdcCode
                FROM Common.RxCui A cross join Common.Ndc B
                WHERE A.Code IN (SELECT RxCuiCode FROM @rxCuiTable) AND B.Code IN (SELECT NdcCode FROM @ndcTable )
            ) S
          ON T.RxCuiId = S.RxCuiId AND T.NdcId = S.NdcId
    WHEN MATCHED THEN 
       UPDATE
          SET T.NdcId = S.NdcId, T.RxCuiId = S.RxCuiId
    WHEN NOT MATCHED THEN
       INSERT ( NdcId, RxCuiId ) VALUES ( S.NdcId, S.RxCuiId);

我遇到的问题是获得正确的映射。在我的C#代码中,我试图找到一种方法来发送每个RxCui和Ndc的列表,而无需在每个标签上进行foreach。

到目前为止我所拥有的是

var data = new DrugLabels();
var productsNdc = data.results.Where(x => x.openfda?.product_ndc?.Count > 0).SelectMany(x => x.openfda.product_ndc).ToArray();
var rxCui = data.results.Where(x => x.openfda?.rxcui?.Count > 0).SelectMany(x => x.openfda.rxcui).ToArray();
await MedicationSearchStoredProcedure(string.Join(",", rxCui), string.Join(",", productsNdc));

前面的代码只有每个rxCui的存储过程映射与我发送的每个Ndc。我想要的是根据标签来映射它们,这是我能想到的唯一方法是使用foreach,就像这样。

foreach(var label in data.results)
{
    await MedicationSearchStoredProcedure(string.Join(",", label.openfda.rxcui), string.Join(",", label.openfda.product_ndc));
}

但那是我不想做的事情。

有什么建议吗? foreach是唯一的方法吗?

1 个答案:

答案 0 :(得分:0)

我建议您获得一个结果数组,然后拨打电话。

List<string> rxcui = new List<string>();
List<string> product_ndc = new List<string>();

foreach(var label in data.results)
{
    rxcui.AddRange(string.Join(",", label.openfda.rxcui));
    product_ndc.AddRange(string.Join(",", label.openfda.product_ndc));
}

await MedicationSearchStoredProcedure(rxcui, product_ndc);