简体   繁体   中英

SqlBulkCopy prevent insert data that null or not in relationship table

I using to extract data from excel and put in sql table as below:

public bool ExtractExcelToDB(int activityId, string tableName, string fileName)
{
    try
    {
        var path = GetPath(activityId);
        path = Path.Combine(path, fileName);

        using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream))
            {
                DataSet result = excelReader.AsDataSet();
                DataTable dt = result.Tables["sheet"];
                DataTable newDt = dt.Select().Skip(1).Take(dt.Rows.Count).CopyToDataTable();

                using (SqlBulkCopy sqlBulk = new SqlBulkCopy(GetConnectionString()))
                {
                    sqlBulk.DestinationTableName = tableName;
                    sqlBulk.WriteToServer(newDt);
                }
            }

            return true;
        }
    }
}

Here is my relationship:

在此处输入图像描述

My issue is that the table that I insert the data has primary key and the data insert to table even the primary key is null or does not exist in the relationship table

How to prevent the data to insert to target table if on of the primary key is null or doesn't exist..

Using the constructor SqlBulkCopy(String, SqlBulkCopyOptions) set the options to check the constraints while performing the insert:

using (SqlBulkCopy sqlBulk = new SqlBulkCopy(GetConnectionString(), SqlBulkCopyOptions.CheckConstraints))
{
    sqlBulk.DestinationTableName = tableName;
    sqlBulk.WriteToServer(newDt);
}

by default the constraints are not checked.

If you can access your Authority table in the same manner you could check the ID values manually as well as follows:

public bool ExtractExcelToDB(int activityId, string tableName, string fileName)
{
    try
    {
        var path = GetPath(activityId);
        path = Path.Combine(path, fileName);

        using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream))
            {
                DataSet result = excelReader.AsDataSet();
                DataTable dt = result.Tables["sheet"];

                // EDIT: Perhaps you can get access the "Authority Table" here as well? e.g.
                DataTable AuthorityTable = result.Tables["AuthoritySheet"];

                // I'll try to do something equivalent
                //DataTable newDt = dt.Select().Skip(1).Take(dt.Rows.Count).CopyToDataTable();
                DataTable newDt = dt.Clone();
                bool firstRow = true;

                foreach (DataRow dr in dt.Rows)
                {
                    if (dr["Id"] != null && !firstRow && AuthorityContainsKey(Convert.ToInt32(dr["Id"]), AuthorityTable))
                        newDt.Rows.Add(dr);
                    else
                        firstRow = false;
                }

                using (SqlBulkCopy sqlBulk = new SqlBulkCopy(GetConnectionString()))
                {
                    sqlBulk.DestinationTableName = tableName;
                    sqlBulk.WriteToServer(newDt);
                }
            }
            return true;
        }
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
}

public bool AuthorityContainsKey(int id, DataTable Auth)
{
    bool result = false;

    foreach (DataRow dr in Auth.Rows)
    {
        if (dr["Id"] != null && Convert.ToInt32(dr["Id"]) == id)
            return true;
    }

    return result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM