当前位置: 首页 > 编程语言 > C#

实体框架批量插入导致KeyNotFoundException错误分享

时间:2023-04-11 10:43:26 C#

实体框架批量插入导致KeyNotFoundException错误我用的是AddRange(),因为AddRange()方法比较慢,需要用到BulkInsert。因此,我通过此处为EF6添加了BulkInsert的NuGet包。添加dll后我得到的第一件事是这个警告:发现同一依赖程序集的不同版本之间存在冲突。请在项目文件中将“AutoGenerateBindingRedirects”属性设置为true。我列出了我所有的联系人实体,需要添加的contactsToInsert(我的联系人在另一个表中也有一个外键)。当我尝试运行以下代码时,我得到一个KeyNotFoundException,声称“给定的键不在字典中”。使用(vardb=newEntities(myConnectionString)){db.批量插入(联系人插入);Db。保存更改();注意。我在BackgroundWorker中运行BulkInsert。这可能是导致问题的原因吗?:c:devEntityFramework.MappingAPItrunksrcEntityFramework.MappingAPIMappingsDbMapping.cs中的EntityFramework.MappingAPI.Mappings.DbMapping..ctor(DbContext上下文)中的第603行:c:devEntityFramework.MappingAPItrunksrcEntityFramework中的EntityFramework.MappingAPI.EfMap.Get(DbContext上下文)中的第101行。MappingAPIEfMap.cs:位于EntityFramework.MappingAPI.Extensions.MappingApiExtensions.Db(DbContextctx,类型类型)的第60行,位于c:devEntityFramework.MappingAPItrunksrcEntityFramework.MappingAPIExtensionsMappingApiExtensions.cs:第51行,位于System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1来源,Func`2keySelector,Func`2elementSelector,IEqualityComparer`1比较器)在System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1source,Func`2keySelector,Func`2elementSelector)atEntityFramework.BulkInsert.Helpers.MappedDataReader`1..ctor(IEnumerable`1enumerable,IEfBulkInsertProviderprovider)inc:devEntityFramework.BulkInsertdevSrcEntityFramework.BulkInsertHelpersMappedDataReader.cs:line58atEntityFramework.BulkInsert.Providers.EfSqlBulkInsertProviderWithMappedDataReader.Run[T](IEnumerable`1entities,SqlTransactiontransaction,BulkInsertOptionsoptions)inc:devEntityFramework.BulkInsertdevSrcEntityFramework.BulkInsertProvidersEfSqlBulkInsertProviderWithMappedDataReader.cs:line22atEntityFramework.BulkInsert.Providers.ProviderBase`2.Run[T](IEnumerable`1实体、IDbTransaction事务、BulkInsertOptions选项)在c:devEntityFramework.BulkInsertdevSrcEntityFramework.BulkInsertProvidersProviderBase.cs中:第77行在EntityFramework.BulkInsert.Providers.ProviderBase`2.Run[T](IEnumerable`1个实体,BulkInsertOptions选项)在c:devEntityFramework.BulkInsertdevSrcEntityFramework.BulkInsertProvidersProviderBase.cs:第109行在EntityFramework.BulkInsert.Extensions.BulkInsertExtension.BulkInsert[T](DbContext上下文,IEnumerable`1实体,SqlBulkCopyOptionssqlBulkCopyFrameworkNullable`1devEntity:batchSize)BulkInsertdevSrcEntityFramework.BulkInsertExtensionsBulkInsertExtension.cs:第95行,位于EntityFramework.BulkInsert.Extensions.BulkInsertExtension.BulkInsert[T](DbContext上下文,IEnumerable`1个实体,Nullable`1batchSize),位于c:devEntityFramework.BulkInsertdevSrcEntityFramework.BulkInsert5中的ProlkInsertExtensions5.Update.bw_DoWork(Objectsender,DoWorkEventArgse)inc:Userspedram.mobediDocumentsVisualStudio2013ProjectsProspectUpdate.cs:line546atSystem.ComponentModel.BackgroundWorker.WorkerThreadStart(Objectargument)通过修改此博客文章中的代码,遇到insert()遇到相同的“字典中不存在给定的键”错误之在此之后,这适用于我的CodeFirstFluentAPI设置这里唯一的依赖项是在上述帖子的DataExtensions片段中找到的ToDataTable()扩展方法。相关部分是GetColumnMappings()方法,它获取POCO类属性的首选名称(您在代码中指定的名称)作为源列名称(在enumerable-turned-datatable中)并将其与元数据成员的名称进行比较(DB)pairedcolumnname)作为目标列名。GetColumnMappings():privateIEnumerableGetColumnMappings(){varstorageMetadata=((EntityConnection)objectContext.Connection).GetMetadataWorkspace().GetItems(DataSpace.SSpace);varentityPropMembers=storageMetadata.Where(s=>(s.BuiltInTypeKind==BuiltInTypeKind.EntityType)).Select(s=>(EntityType)s).Where(p=>p.Name==typeof(T).Name).Select(p=>(IEnumerable)(p.MetadataProperties["Members"].Value)).First();varsourceColumns=entityPropMembers.Select(m=>(string)m.MetadataProperties["PreferredName"].Value);vardestinationColumns=entityPropMembers.Select(m=>m.Name);返回Enumerable.Zip(sourceColumns,destinationColumns,(s,d)=>newSqlBulkCopyColumnMapping(s,d));}完整代码://修改自:https://ruijarimba.wordpress.com/2012/03/25/bulk-insert-dot-net-applications-part1和//https://ruijarimba.wordpress.com/2012/03/18/entity-framework-get-mapped-table-name-from-an-entity/内部类BulkInserter{privatereadonlyObjectContext对象上下文;私有只读IDbConnection连接;内部BulkInserter(DbContextcontextAdapter){objectContext=((IObjectContextAdapter)contextAdapter).ObjectContext;connection=contextAdapter.Database.Connection;}publicvoidInsert(IEnumerableitems)whereT:class{EnsureOpenConnection();使用(varbulkCopy=newSqlBulkCopy((SqlConnection)connection){DestinationTableName=GetTableName(),}){foreach(varmappinginGetColumnMappings()){bulkCopy.ColumnMappings.Add(mapping);}bulkCopy.WriteToServer(items.ToDataTable());}}privatevoidEnsureOpenConnection(){if(connection.State==ConnectionState.Closed){connection.Open();}}[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design","CA1004:GenericMethodsShouldProvideTypeParameter")]privatestringGetTableName()其中T:class{stringsql=objectContext.CreateObjectSet().ToTraceString();正则表达式regex=newRegex("FROM(?.*)AS");匹配match=regex.Match(sql);stringtable=match.Groups["table"].Value;返回表;}privateIEnumerableGetColumnMappings(){varstorageMetadata=((EntityConnection)objectContext.Connection).GetMetadataWorkspace().GetItems(DataSpace.SSpace);varentityPropMembers=storageMetadata.Where(s=>(s.BuiltInTypeKind==BuiltInTypeKind.EntityType)).Select(s=>(EntityType)s).Where(p=>p.Name==typeof(T).Name).Select(p=>(IEnumerable)(p.MetadataProperties["Members"].Value)).First();varsourceColumns=entityPropMembers.Select(m=>(string)m.MetadataProperties["PreferredName"].Value);vardestinationColumns=entityPropMembers.Select(m=>m.Name);返回Enumerable.Zip(sourceColumns,destinationColumns,(s,d)=>newSqlBulkCopyColumnMapping(s,d));好吧,我遇到了同样的错误并且在网上找不到任何答案,所以不得不深入研究,所以这就是我的想法:部分时间它会标记这样的错误,其次,不确定为什么它需要新的DbContext仅具有bulkInsertions的相关实体,如果有任何其他实体,它会抛出相同的错误所以这是第二个原因,所以我必须解决这两个问题并像马一样奔跑!值得一试,所以试一试“BulkInsert”库非常快,但不是很灵活且不受支持。它不支持所有类型的继承(TPC、TPT)并且在列映射方面存在一些问题。您遇到的问题是由于以下原因之一。免责声明:我是EntityFrameworkExtensions项目的所有者该库是性能的终极库,允许:支持所有继承和关联。例:以上就是C#学习教程:实体框架批量插入导致KeyNotFoundException错误分享的全部内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——using(vardb=newEntities(myConnectionString){db.BulkInsert(contactsToInsert);}//BulkSaveChanges比慢BulkInsert但比SaveChanges快得多侵权请点击维权联系管理员删除如转载请注明出处:

最新推荐
猜你喜欢