2015-08-26 10 views
9

मैं EF6 का उपयोग कर रहा हूं और AddRange() विधि की निम्न गति के कारण मुझे BulkInsert का उपयोग करने की आवश्यकता है। इसलिए मैंने here के माध्यम से EF6 के लिए BulkInsert के NuGet पैकेज को जोड़ा।इकाई फ्रेमवर्क थोक सम्मिलित करें KeyNotFoundException त्रुटि

ही निर्भर विधानसभा के विभिन्न संस्करणों के बीच

मिले संघर्ष:

पहली बात मैं dll रों जोड़ने के बाद प्राप्त इस चेतावनी थी। कृपया प्रोजेक्ट फ़ाइल में "AutoGenerateBindingRedirects" प्रॉपर्टी को पर सेट करें।

मैं (भी मेरे संपर्क एक और तालिका में एक विदेशी कुंजी है,) मेरे सारे Contact संस्थाओं अर्थात् contactsToInsert जोड़ा जाना चाहिए इस बात का एक List बनाया है। मैं एक KeyNotFoundException दावा है कि "दिया कुंजी शब्दकोश में मौजूद नहीं थे" प्राप्त जब मैं निम्नलिखित कोड को चलाने की कोशिश की।

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

एनबी। मैं BackgroundWorker के अंदर बल्कइन्सर्ट चला रहा हूं। क्या यह संभवतः this fix द्वारा निर्धारित मुद्दे का कारण हो सकता है?

StackTrace:

एक विरासत जब आपके इकाई है और:

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) 
+1

मैं सही बात में चलाने की है, और नहीं इस के लिए एक सुधार ढूंढने करने में सक्षम है। आखिरकार, मुझे कोई दूसरा ईएफ संदर्भ बनाना था जिसमें कोई नेविगेशन गुण नहीं था और केवल वह वर्ग जिसे मैं थोक Insert का उपयोग करके सम्मिलित करने की कोशिश कर रहा हूं। यह सिर्फ एक कामकाज है, और निश्चित रूप से एक फिक्स नहीं है, लेकिन यह मुझे काम करने की अनुमति देता है। –

+0

क्या आपने 6.1.3 के साथ काम कर रहे नवीनतम संस्करणों की जांच की थी। मैंने अब कुछ परियोजनाओं के लिए पुस्तकालयों का उपयोग किया है, अब तक कोई समस्या नहीं है :)। एक और बिंदु: क्या आप अपनी संपर्क कक्षा परिभाषा प्रदान कर सकते हैं? –

उत्तर

0

ठीक है, मैं एक ही गलती किसी भी जवाब मिल ऑनलाइन सके था इतनी गहरी इसलिए यहाँ देखने के लिए किया था मैं क्या सोचा है बच्चे संस्थाओं अगर DBSet यह झंडे के हिस्से के रूप में परिभाषित नहीं एक त्रुटि इस तरह, दूसरी बात, यकीन नहीं क्यों यह सिर्फ संबंधित bulkInsertions के लिए इस्तेमाल अगर कोई अन्य संस्थाओं है वहाँ यह एक ही त्रुटि को जन्म देती है इकाई के साथ नए DbContext की उम्मीद है।

तो इसके 2 कारण तो मैं इन दोनों ठीक करने के लिए किया था, और एक घोड़े की तरह चल रहा है !!!

इसके लायक कोशिश कर

, तो एक कोशिश

-1

"BulkInsert" पुस्तकालय बहुत तेजी से लेकिन बहुत लचीला नहीं और असमर्थित है दे।

यह विरासत के सभी प्रकार (टीपीसी, टीपीटी) का समर्थन नहीं करता और स्तंभ मानचित्रण के साथ कुछ समस्या है।

मुद्दा आप मिल गया इन कारणों में से एक के लिए है।

अस्वीकरण: मैं परियोजना Entity Framework Extensions

इस पुस्तकालय प्रदर्शन के लिए परम पुस्तकालय है के मालिक हूँ और करने की अनुमति:

  • BulkSaveChanges
  • BulkInsert
  • BulkUpdate
  • बल्कडेले
  • बल्कमेर्ज

सभी विरासत और सहयोगी समर्थित हैं।

उदाहरण:

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

// BulkSaveChanges is slower than BulkInsert but way faster then SaveChanges 
using (var db = new Entities(myConnectionString)) 
{ 
    db.Contacts.AddRange(contactsToInsert); 
    db.BulkSaveChanges(); 
} 
+3

आपको शायद यह उल्लेख करना चाहिए कि यह मुफ्त नहीं है, यहां तक ​​कि जीपीएल भी नहीं। –

2

this blog post में कोड में संशोधन के साथ, यहाँ क्या BulkInsert() पर एक ही "The given key was not present in the dictionary" त्रुटि का सामना करने के बाद अपने कोड पहले Fluent एपीआई सेटअप के लिए काम किया है। उपर्युक्त पोस्ट के DataExtensions स्निपेट में मिली ToDataTable() एक्सटेंशन विधि केवल एकमात्र निर्भरता है।

प्रासंगिक हिस्सा GetColumnMappings() तरीका है जिसके POCO वर्ग संपत्ति के पसंदीदा नाम (एक आप कोड में निर्दिष्ट) और साथ जोड़े यह मेटाडाटा सदस्य (गणनीय बने datatable में) स्रोत स्तंभ नाम के रूप में हो जाता है है गंतव्य कॉलम नाम के रूप में नाम (डीबी कॉलम नाम)।

GetColumnMappings():

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)); 
    } 
} 
+0

देरी के लिए खेद है। यह एक साल पहले पोस्ट किया गया था। जैसे ही मैं उस परियोजना पर वापस आऊंगा, मैं जांच करूँगा और इस पर वापस आऊंगा। – Disasterkid

संबंधित मुद्दे