【问题标题】:EF.BulkInsert and Glimpse - not playing together wellEF.BulkInsert 和 Glimpse - 不能很好地配合
【发布时间】:2016-07-07 14:27:22
【问题描述】:

我有一个 EF6 / ASP.NET 4.5 Webforms 解决方案启动并运行,现在我需要添加一些功能以允许从 Excel 文件批量插入。

我知道开箱即用的 EF 并未针对批量操作进行优化,因此我环顾四周并找到了“EF BulkInsert”(https://efbulkinsert.codeplex.com/) 来促进这一点。

我在一个测试应用程序中尝试过它,效果非常好 - 但是当我将它包含在我的实际主应用程序中时,它就崩溃了。尝试执行实际的批量插入调用时,系统崩溃并出现异常:

BulkInsertProviderNotFoundException:找不到“Glimpse.Ado.AlternateType.GlimpseDbConnection”的 BulkInsertProvider。要注册新的提供者,请使用 EntityFramework.BulkInsert.ProviderFactory.Register() 方法'

现在我不确定这是否是 GlimpseEF BulkInsert(或两者)的错,不幸的是,我似乎找不到任何解决方案 - 两者都没有这些软件的制造商正在提供任何见解或解决方法....

这里有没有人偶然发现了同样的问题,并找到了解决方案?

【问题讨论】:

    标签: entity-framework-6 asp.net-4.5 glimpse ef-bulkinsert


    【解决方案1】:

    出现此问题是因为 Glimpse 包装了 DbConnection 并且 EF BulkInsert 扩展试图访问其不存在的私有字段“_connectionString”。 在这种情况下,我会责怪 EF BulkInsert,因为访问私有成员只是一种不好的做法,而且 Glimpse 团队中的任何开发人员都无法预料到这一点。

    为了解决这个问题,我编写了一个继承自 EfSqlBulkInsertProviderWithMappedDataReader(默认提供程序)的自定义:

        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"); }
            }
        }
    

    现在在某处注册此提供程序。我是在上下文 OnModelCreating 方法中完成的。

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

    请注意,我仅使用 EF BulkInsert 的基本用法对此进行了测试。

    【讨论】:

    • 谢谢,这真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    相关资源
    最近更新 更多