【问题标题】:How to avoid distinct records from database while inserting data using asp.net?使用asp.net插入数据时如何避免数据库中的不同记录?
【发布时间】:2019-09-26 08:32:07
【问题描述】:

我正在构建一个程序,将数据从 Excel 文件导入数据库,或通过写入文本框(通过在 asp.net 中插入)或两者兼而有之,但我想在用户尝试输入时发出警告数据库中已有的相同记录(重复)。

我想通过在 SQL 中编码或设置一些东西来做到这一点,以使用户更容易......

这是我的桌子:

Mov. Date     Value Date    description of the movement     Value in EUROS
---------------------------------------------------------------------------
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 222       200,01
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 223       200,01
12-12-2001    12-12-2001    DEPOSITO EM NUMERARIO 224       200,02

如果用户输入的记录等于其中任何一个,它会发出警告,用户可以再试一次

这是代码(asp.net C#):

protected void Upload_Click(object sender, EventArgs e)
{
    string excelPath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
    string filepath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.FileName);
    string filename = Path.GetFileName(filepath);

    FileUpload1.SaveAs(excelPath);

    string ext = Path.GetExtension(filename);

    string strConnection = @"Data Source=PEDRO-PC\SQLEXPRESS;Initial Catalog=costumizado;Persist Security Info=True;User ID=sa;Password=1234";
    string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\"";

    OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);

    OleDbCommand cmd = new OleDbCommand("Select * from [rptListaMovs_4$A15:D75]", excelConnection);

    excelConnection.Open();
    cmd.ExecuteNonQuery();

    OleDbDataReader dReader;
    dReader = cmd.ExecuteReader();

    DataTable dtFail = new DataTable();

    using (SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection))
    {
        sqlBulk.ColumnMappings.Add("Mov. Date", "Mov. Date");
        sqlBulk.ColumnMappings.Add("Value Date", "Value Date");
        sqlBulk.ColumnMappings.Add("description of the movement", "description of the movement");
        sqlBulk.ColumnMappings.Add("Value in EUROS", "Value in EUROS");
        sqlBulk.DestinationTableName = "Dados";

        var temp = dtFail.AsEnumerable().Distinct();

        dtFail = temp.CopyToDataTable();

        sqlBulk.WriteToServer(dReader);
    }

    excelConnection.Close();
}

【问题讨论】:

  • 您可以在列上添加唯一性约束,或者选择 * 并在内存中执行验证
  • @Daniel 不能对列进行唯一约束,否则我不能在不同的记录中拥有两个相等的值。我只是不希望我的程序让用户错误地输入两行......你在说的第二件事是什么?
  • 只是一种预感,但您在 DataTables 集合上调用 Linqs .Distinct。这可能使用引用相等并失败。我认为最简单的方法是将表单数据解析为值类型结构的集合,然后使用 .GroupBy(x => x) .Where(g => g.Count() > 1) 之类的东西来检查是否有任何重复。
  • 如果你做 SQL 你可以简单地做一个合并语句,如果它匹配然后更新,它不匹配插入。您可以做的另一件事是使用 SQL 输出功能获取输入的 id 并将其从列表中删除,然后再继续。
  • 当你得到答案时不要删除你的问题。见meta.stackoverflow.com/questions/378440/…

标签: c# asp.net sql-server excel


【解决方案1】:

SqlBulkCopy 不是用于条件插入的正确工具。您需要使用合并语句或IF NOT EXISTS (SELECT ....) INSERT ELSE UPDATE

如果您需要提交大量数据,请查看使用表类型Table-Valued Parameter 和存储过程来封装条件插入/更新逻辑。

如果需要在找到匹配项时向用户显示消息,则添加一列以包含行中所有数据的哈希值可能会有所帮助,因此您可以执行查找和消息或过滤掉匹配项。或者如前所述,使用OUTPUT SQL 子句创建要返回的匹配列表。

CREATE TYPE <MyRecord> (
    <add columns to match the table as if it was a CREATE TABLE>
)

将DataTable作为参数绑定到存储过程

...
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "<MyRecord>";
command.ExecuteNonQuery();
...

现有帖子Pass table value parameter中的示例

【讨论】:

  • 但是我不必总是写这个?由于这是针对客户的,因此他将无法为此使用 Sql,我需要为他编程...通过网络应用程序
  • 这就是存储过程的目的。它封装了数据库逻辑,通过代码启动。 Example
猜你喜欢
  • 1970-01-01
  • 2017-10-11
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2014-08-28
  • 2016-03-22
相关资源
最近更新 更多