实体框架批量插入抛出 KeyNotFoundException 错误

2023-11-25

我在用EF6并且由于速度低AddRange()我需要使用的方法BulkInsert。所以我通过以下方式添加了 BulkInsert for EF6 的 NuGet 包here.

添加后我收到的第一件事dll是这个警告:

发现同一依赖的不同版本之间存在冲突 集会。请将“AutoGenerateBindingRedirects”属性设置为 在项目文件中为 true。

我制造了一个List我所有的Contact实体即要插入的联系人需要添加(我的联系人在另一个表中也有外键)。当我尝试运行以下代码时,我收到一个KeyNotFoundException声称“字典中不存在给定的键".

using (var db = new Entities(myConnectionString))
{
    db.BulkInsert(contactsToInsert);
    db.SaveChanges();
}

NB.我正在运行 BulkInsertBackgroundWorker。这可能是问题的原因吗?this fix?

堆栈跟踪:

   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at EntityFramework.MappingAPI.Mappers.MapperBase.BindForeignKeys() in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappers\MapperBase.cs:line 603
   at EntityFramework.MappingAPI.Mappings.DbMapping..ctor(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Mappings\DbMapping.cs:line 101
   at EntityFramework.MappingAPI.EfMap.Get(DbContext context) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\EfMap.cs:line 60
   at EntityFramework.MappingAPI.Extensions.MappingApiExtensions.Db(DbContext ctx, Type type) in c:\dev\EntityFramework.MappingAPI\trunk\src\EntityFramework.MappingAPI\Extensions\MappingApiExtensions.cs:line 51
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at EntityFramework.BulkInsert.Helpers.MappedDataReader`1..ctor(IEnumerable`1 enumerable, IEfBulkInsertProvider provider) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Helpers\MappedDataReader.cs:line 58
   at EntityFramework.BulkInsert.Providers.EfSqlBulkInsertProviderWithMappedDataReader.Run[T](IEnumerable`1 entities, SqlTransaction transaction, BulkInsertOptions options) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Providers\EfSqlBulkInsertProviderWithMappedDataReader.cs:line 22
   at EntityFramework.BulkInsert.Providers.ProviderBase`2.Run[T](IEnumerable`1 entities, IDbTransaction transaction, BulkInsertOptions options) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Providers\ProviderBase.cs:line 77
   at EntityFramework.BulkInsert.Providers.ProviderBase`2.Run[T](IEnumerable`1 entities, BulkInsertOptions options) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Providers\ProviderBase.cs:line 109
   at EntityFramework.BulkInsert.Extensions.BulkInsertExtension.BulkInsert[T](DbContext context, IEnumerable`1 entities, SqlBulkCopyOptions sqlBulkCopyOptions, Nullable`1 batchSize) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Extensions\BulkInsertExtension.cs:line 95
   at EntityFramework.BulkInsert.Extensions.BulkInsertExtension.BulkInsert[T](DbContext context, IEnumerable`1 entities, Nullable`1 batchSize) in c:\dev\EntityFramework.BulkInsert\dev\Src\EntityFramework.BulkInsert\Extensions\BulkInsertExtension.cs:line 75
   at Prospect.Update.bw_DoWork(Object sender, DoWorkEventArgs e) in c:\Users\pedram.mobedi\Documents\Visual Studio 2013\Projects\Prospect\Update.cs:line 546
   at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

修改代码后这篇博文,这是在遇到相同问题后对我的 Code First Fluent API 设置有效的方法"The given key was not present in the dictionary"错误BulkInsert()。这里唯一的依赖是ToDataTable()中找到的扩展方法DataExtensions上述帖子的片段。

相关部分是GetColumnMappings()获取 POCO 类属性的方法首选名称(您在代码中指定的)作为源列名称(在可枚举的数据表中)并将其与元数据成员的name(数据库列名称)作为目标列名称。

获取列映射():

private IEnumerable<SqlBulkCopyColumnMapping> GetColumnMappings<T>()
{
    var storageMetadata = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace().GetItems(DataSpace.SSpace);
    var entityPropMembers = storageMetadata
        .Where(s => (s.BuiltInTypeKind == BuiltInTypeKind.EntityType))
        .Select(s => (EntityType)s)
        .Where(p => p.Name == typeof(T).Name)
        .Select(p => (IEnumerable<EdmMember>)(p.MetadataProperties["Members"].Value))
        .First();

    var sourceColumns = entityPropMembers.Select(m => (string)m.MetadataProperties["PreferredName"].Value);
    var destinationColumns = entityPropMembers.Select(m => m.Name);

    return Enumerable.Zip(sourceColumns, destinationColumns, (s, d) => new SqlBulkCopyColumnMapping(s, d));
}

完整代码:

// Modified from: https://ruijarimba.wordpress.com/2012/03/25/bulk-insert-dot-net-applications-part1 and
// https://ruijarimba.wordpress.com/2012/03/18/entity-framework-get-mapped-table-name-from-an-entity/

internal class BulkInserter
{
    private readonly ObjectContext objectContext;

    private readonly IDbConnection connection;

    internal BulkInserter(DbContext contextAdapter)
    {
        objectContext = ((IObjectContextAdapter)contextAdapter).ObjectContext;
        connection = contextAdapter.Database.Connection;
    }

    public void Insert<T>(IEnumerable<T> items) where T : class
    {
        EnsureOpenConnection();
        using (var bulkCopy = new SqlBulkCopy((SqlConnection)connection)
        {
            DestinationTableName = GetTableName<T>(),
        })
        {
            foreach (var mapping in GetColumnMappings<T>())
            {
                bulkCopy.ColumnMappings.Add(mapping);
            }

            bulkCopy.WriteToServer(items.ToDataTable());
        }
    }
    private void EnsureOpenConnection()
    {
        if (connection.State == ConnectionState.Closed)
        {
            connection.Open();
        }
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
    private string GetTableName<T>() where T : class
    {
        string sql = objectContext.CreateObjectSet<T>().ToTraceString();
        Regex regex = new Regex("FROM (?<table>.*) AS");
        Match match = regex.Match(sql);

        string table = match.Groups["table"].Value;
        return table;
    }

    private IEnumerable<SqlBulkCopyColumnMapping> GetColumnMappings<T>()
    {
        var storageMetadata = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace().GetItems(DataSpace.SSpace);
        var entityPropMembers = storageMetadata
            .Where(s => (s.BuiltInTypeKind == BuiltInTypeKind.EntityType))
            .Select(s => (EntityType)s)
            .Where(p => p.Name == typeof(T).Name)
            .Select(p => (IEnumerable<EdmMember>)(p.MetadataProperties["Members"].Value))
            .First();

        var sourceColumns = entityPropMembers.Select(m => (string)m.MetadataProperties["PreferredName"].Value);
        var destinationColumns = entityPropMembers.Select(m => m.Name);

        return Enumerable.Zip(sourceColumns, destinationColumns, (s, d) => new SqlBulkCopyColumnMapping(s, d));
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架批量插入抛出 KeyNotFoundException 错误 的相关文章

随机推荐

  • 从 Python >单独启动另一个程序<

    我正在尝试运行一个与 Python 无关的外部程序 通常这不会有问题 但该程序是一个游戏 并且内置了一个 Python 解释器 当我使用 subprocess Popen 时 它会启动单独的程序 但在原始程序的 Python 实例下执行此操
  • Julia 中使用匿名函数的性能损失

    我注意到在 Julia 中使用匿名函数会带来性能损失 为了说明这一点 我有两个快速排序的实现 取自 Julia 发行版中的微观性能基准 第一个按升序排列 function qsort a lo hi i j lo hi while i lt
  • time.time 与 timeit.timeit

    有时 我喜欢计算部分代码的运行时间 我检查了很多在线网站 大致上看到了两种主要方法 一种正在使用time time另一个正在使用timeit timeit 因此 我编写了一个非常简单的脚本来比较两者 from timeit import t
  • Google 脚本仅在工作日触发

    我有一个用 Google 文档创建的工具 其中一部分是我每天上午 11 点备份一组数字 我用它来创建一个图表来显示一段时间内的进度 我使用触发器运行此脚本 该触发器设置为每周备份一次数据 我真正想做的只是在工作日备份这些数据 因为周末的数据
  • 集群环境下运行的Spring定时任务

    我正在编写一个应用程序 它有一个每 60 秒执行一次的 cron 作业 该应用程序配置为在需要时扩展到多个实例 我只想每 60 秒在 1 个实例上执行该任务 在任何节点上 我找不到开箱即用的解决方案 而且我很惊讶以前没有多次询问过这个问题
  • 如何获取字符串中给定名称的变量的值? [复制]

    这个问题在这里已经有答案了 为简单起见 这是我想要做的事情的精简版本 def foo a I want to print the value of the variable the name of which is contained in
  • 修复了位置在 Windows Safari 上不起作用的问题

    我的画廊有问题 位置 固定 并且网站内容正在其上滚动 该位置固定在每个浏览器中都有效 除了 Windows 7 上的 Safari 是的 它甚至在 IE8 和 Mac 上的 Safari 中也有效 顶部已定义 但它仍然充当相对位置并与其余内
  • Androidcamera2 API获取AF模式下的焦距

    我正在使用 Android Camera2 API 我可以在手动对焦模式下使用 LENS FOCUS DISTANCE 获取焦距值 然而 在 AF 模式下该属性始终为零 有什么方法可以获取AF模式下的焦距吗 距镜片最前表面的最短距离 成为焦
  • JSF 2 ui:repeat:将 div 内的每 n 个项目分组

    给定一个集合 我想在这样的页面上排列 div div div div div div div div div div div div div div div div
  • Android 中 Json 到 POJO 的映射

    在 Android 中通过 Rest Framework 处理 json 有哪些好的做法 例如 如果我得到如下所示的某个 json 结果 或任何其他结果 我只是给出更复杂的结果 lifts id 26 time 2012 11 21T12
  • iPhone 和 Android 可以录制和播放哪种音频格式?

    我正在设计一个应用程序 可以在 iPhone 和 Android 上录制短音频文件 并可以在这两个平台上播放 希望也可以在任何其他智能手机上播放 现在我正在使用 caf 和 iLBC 编解码器 因为我知道 iPhone 不编码 mp3 在这
  • 大规模编排与编排的面向服务的架构?

    我是一家大型金融公司的架构师 我们正开始在不同国家实施一个新的面向业务的信息系统 从一开始 核心思想就是尽可能遵循面向微服务的原则 并确保工程师已阅读 Sam Newman 撰写的 构建微服务 一书 现在我已经来到了十字路口 我们的服务主要
  • 从 COPY 命令获取行数

    从文件复制数据时 您可以使用 命令标签 获取 psql 中的行数 db COPY t FROM var lib postgres test sql COPY 10 我需要行数并希望避免冗余count 在桌子上 有没有办法得到这个计数COPY
  • 安全地从字典中删除多个键

    我知道如何删除条目 key 从我的字典里d 安全 你做 if d has key key del d key 但是 我需要安全地从字典中删除多个条目 我正在考虑定义元组中的条目 因为我需要多次执行此操作 entities to remove
  • MongoDB 副本集没有主节点,需要强制创建新的主节点

    我们有一个 mongoDB 副本集 有 3 个节点 Primary 中学 Arbiter 不知何故 我们的副本集最终 1 和 2 都被设置为次要成员 我不确定这是如何发生的 我们进行了服务器迁移 其中一个节点在其上运行 但只有一个 不管怎样
  • Google 地图 API:标记图像定位

    我已经更改了用于marker在谷歌地图上 新图像比旧图像宽得多 我注意到标记与旧图像对齐lat and lng以便标记位于其水平中点上方lat and lng 这不是我想要的 我想要的是lat and lng与左侧的标记对齐 我想偏移mar
  • “溢出”编译器错误 -9223372036854775808L

    的范围长数据类型 is 9223372036854775808 to 9223372036854775807 但以下语句会生成编译器错误 BC30036 溢出 Dim a As Long 9223372036854775808L 在线尝试一
  • HTML/CSS - 为什么打印时背景颜色变成白色?

    打印时 我的背景颜色甚至元素的字体颜色突然变成白色 这是一个示例标记 div div
  • Crystal Report(或 SSRS)在图像周围流动文本

    我想在水晶报表中有这样的布局 我怎样才能做到这一点 如果无法在 CR 或 SSRS 中完成 是否还有其他替代方案 我不相信水晶报表可以做到这一点 我对 SSRS 不太熟悉 但在查看了现场选项后 我也不相信它可以用它来完成 通常 现场位置在报
  • 实体框架批量插入抛出 KeyNotFoundException 错误

    我在用EF6并且由于速度低AddRange 我需要使用的方法BulkInsert 所以我通过以下方式添加了 BulkInsert for EF6 的 NuGet 包here 添加后我收到的第一件事dll是这个警告 发现同一依赖的不同版本之间