2016-07-07 24 views
4

Ich habe eine EF6/ASP.NET 4.5 Webforms-Lösung zum Laufen gebracht, und jetzt muss ich einige Funktionen hinzufügen, um Masseneinfügungen von Excel-Dateien zu ermöglichen.EF.BulkInsert und Glimpse - nicht gut zusammen spielen

Ich bin mir bewusst, dass EF out of the Box nicht für Bulk-Operationen optimiert ist, so schaute ich mich um und fand "EF BulkInsert" (https://efbulkinsert.codeplex.com/), nur um dies zu erleichtern.

Ich habe es in einer Test-App versucht, und es hat wunderbar funktioniert - aber als ich es in meine eigentliche Haupt-App einfügte, brach es zusammen. Beim Versuch, die tatsächliche Masseneinfügung Anruf zu tun, stürzt das System mit einer Ausnahme:

BulkInsertProviderNotFoundException: BulkInsertProvider nicht für ‚Glimpse.Ado.AlternateType.GlimpseDbConnection gefunden. Um sich anzumelden neuen Provider Verwendung EntityFramework.BulkInsert.ProviderFactory.Register() Methode‘

Jetzt bin ich nicht sicher, ob dies die Schuld der ist Glimpse oder EF BulkInsert (oder beides), und leider habe ich scheint keine Lösung zu finden - keiner der Macher dieser Software bietet Einblicke oder Workarounds ...

Ist hier jemand über das gleiche Problem gestolpert und hat eine Lösung dafür gefunden ??

Antwort

6

Dieses Problem tritt auf, weil Glimpse hüllt DbConnection und EF BulkInsert Erweiterung zuzugreifen versucht es privaten Bereich „_connectionString“ ist, das nicht da ist. Ich würde Schuld EF BulkInsert in diesem Fall als Zugriff auf private Mitglieder ist nur schlechte Praxis und kein Entwickler in Glimpse Team könnte dies vorausgesehen haben.

Um dieses Problem zu lösen ich eine benutzerdefinierte geschrieben haben, die sich von EfSqlBulkInsertProviderWithMappedDataReader (Standardanbieter) erbt:

public class GlimpseProvider : EfSqlBulkInsertProviderWithMappedDataReader, IEfBulkInsertProvider 
    { 

     private static object GetPrivateFieldValue(object obj, string propName) { 
      if (obj == null) throw new ArgumentNullException("obj"); 
      Type t = obj.GetType(); 
      FieldInfo fieldInfo = null; 
      PropertyInfo propertyInfo = null; 
      while (fieldInfo == null && propertyInfo == null && t != null) { 
       fieldInfo = t.GetField(propName, 
        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
       if (fieldInfo == null) { 
        propertyInfo = t.GetProperty(propName, 
         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
       } 

       t = t.BaseType; 
      } 
      if (fieldInfo == null && propertyInfo == null) 
       throw new ArgumentOutOfRangeException("propName", 
        string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName)); 

      if (fieldInfo != null) 
       return fieldInfo.GetValue(obj); 

      return propertyInfo.GetValue(obj, null); 
     } 

     protected override IDbConnection DbConnection { 
      get { return (IDbConnection)GetPrivateFieldValue(this.Context.Database.Connection, "InnerConnection"); } 
     } 
    } 

Jetzt irgendwo diesen Anbieter registrieren. Ich habe es im Kontext OnModelCreating-Methode gemacht.

EntityFramework.BulkInsert.ProviderFactory.Register<GlimpseProvider>("Glimpse.Ado.AlternateType.GlimpseDbConnection"); 

Beachten Sie, dass ich diese grundlegende Verwendung von EF BulkInsert nur mit getestet haben.

+1

Vielen Dank - funktioniert wie ein Charme! –

+0

Danke, das war wirklich hilfreich! –