Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DBML如何从插入时违反唯一密钥的情况中恢复?_C#_Sql Server_Dbml_Insertonsubmit - Fatal编程技术网

C# DBML如何从插入时违反唯一密钥的情况中恢复?

C# DBML如何从插入时违反唯一密钥的情况中恢复?,c#,sql-server,dbml,insertonsubmit,C#,Sql Server,Dbml,Insertonsubmit,我想了解如何在插入时从DBML中的唯一密钥冲突错误中恢复 我的设想: 创建一个新的DBML映射对象(称为a)(可能是重复的,但之前无法确定),并使用InsertOnSubmit(a) 然后在上下文中,我调用SubmitChanges(ConflictMode.ContinueOnConflict) 我捕获错误并尝试通过OverwriteCurrentValues 当我重试SubmitChanges时,我得到了相同的错误 代码: 因此,当我插入了重复的日期,并且在第二次SubmitChanges(

我想了解如何在插入时从DBML中的唯一密钥冲突错误中恢复

我的设想:

  • 创建一个新的DBML映射对象(称为a)(可能是重复的,但之前无法确定),并使用
    InsertOnSubmit(a)
  • 然后在上下文中,我调用
    SubmitChanges(ConflictMode.ContinueOnConflict)
  • 我捕获错误并尝试通过
    OverwriteCurrentValues
  • 当我重试
    SubmitChanges
    时,我得到了相同的错误
  • 代码:

    因此,当我插入了重复的日期,并且在第二次
    SubmitChanges()
    调用中引发了相同的异常时,这些问题永远不会得到解决

    如何从错误中恢复以成功调用
    SubmitChanges()

    我正在寻找一种解决方案,以便在更复杂的ETL处理代码中使用。在我提交更改之前,应该对多行和每行运行10个或更多维度。
    我不介意唯一的约束错误——它们意味着我想插入的值已经在数据库中了,我对此很满意。接下来的步骤是为每个维度替换代理键,并插入或更新事实表(不包括在本例中)。

    对此的首选解决方案是:

            var date = new DateTime(2014, 1, 1);
            if (!db_context.dimension_dates.Any(x => x.Date == date))
            {
                var new_date_row = new dimension_date();
                // two columns: datetime date, identity key
                new_date_row.Date = date;
                db_context.dimension_dates.InsertOnSubmit(new_date_row);
                db_context.SubmitChanges();
            }
    

    在尝试添加新数据之前,为什么不检查db_context.dimension_日期?这样你就可以避免这个问题了。如果您的目的是更新包含相同PK的行,则更新它,而不是尝试插入新的行,或者先删除现有行。因此,我打算在多个实例上并行运行此代码,除非它被锁定在事务中,我无法确定另一个进程是否没有插入新维度,这意味着我找到了部分解决方案—在catch语句中插入代码:
    foreach(在db_context.GetChangeSet().Inserts中插入var){db_context.GetTable(insert.GetType()).deleteosubmit(insert);}
    但是,这将删除所有更改,而不仅仅是失败的更改-不够好!如果(!db_context.dimension_dates.Any(x=>x.Date==Date))更好。在不需要的情况下检索值效率很低。嗨,Rob,谢谢你的时间和回答,我应该添加它是更大的ETL处理器代码的一部分,我不能在每个维度都更新的情况下提交更改。我计划在提交更改之前添加数百到数千个单个更改。然后,我将从示例中删除SubmitChanges()调用,并在循环完成或达到配置的批大小时调用SubmitChanges()。您是否针对ETL需求而不是定制C#调查了SSI?在顶部看到您的评论,您能否基于目标实体进行并行化以消除在两个不同线程中处理同一实体两次的问题?我正在重新编写现有SSI,因为当相关存储过程增长超过2k行时,这将变得不可管理。基于自定义linq查询和智能连接的C#也快得多。
            var date = new DateTime(2014, 1, 1);
            if (!db_context.dimension_dates.Any(x => x.Date == date))
            {
                var new_date_row = new dimension_date();
                // two columns: datetime date, identity key
                new_date_row.Date = date;
                db_context.dimension_dates.InsertOnSubmit(new_date_row);
                db_context.SubmitChanges();
            }