c# - 内存泄漏 Entity Framework

标签 c# .net entity-framework entity-framework-4 sql-server-ce

当我将 Entity Framework 与 SQL Server Compact Edition 结合使用时出现内存泄漏。我的情况:

我有一个大约 600MByte 的文件。我逐行阅读它,创建一个实体类并将其添加到 SQL Server CE 数据库中。它的内存增长非常快。 Gen 0 Collections 计数器和 Gen 2 Heap Size 增长非常快(来自 Process Explorer 的信息)。如果我理解正确的话,Gen 2 Heap 适用于大对象。我认为我的实体类是一个大对象。所以 Entity Framework 保存我的对象并且不释放它们。我已经尝试分离它们并调用 GC.Collect(2) 但它没有帮助。

首先我读了这行。然后在解析该行后创建一个对象。然后将其添加到数据库中。这是我的数据库代码:

DBEntities dbConnection = new DBEntities();
dbConnection.My_Table.AddObject(MyObjectCreatedFromTheLine);
dbConnection.SaveChanges();
//  dbConnection.Detach(MyObjectCreatedFromTheLine);
//  dbConnection.Dispose();
MyObjectCreatedFromTheLine = null;
dbConnection = null;

我还读到创建的实体类 (MyObjectCreatedFromTheLine) 属于 DbContext。所以我为每一行调用这段代码,每次都创建一个新的上下文。

我做错了什么?

最佳答案

我在尝试使用 Entity Framework 将 50,000 多条记录插入 SQL 数据库时遇到了这个问题。 Entity Framework 不适用于大量操作(大量插入或删除操作),因此我最终使用了 System.Data.SqlClient.SqlBulkCopy 库,它更加高效和快速。我什至编写了下面的辅助函数来自动映射,这样我就不必手动构造 SQL Insert 语句。 (它几乎与类型无关!我认为)。

基本上工作流程是:IList -> DataTable -> SqlBulkCopy

public static void BulkInsert<T>(string connection, string tableName, IList<T> list)
    {
        using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepNulls))
        {
            bulkCopy.BatchSize = list.Count;
            bulkCopy.DestinationTableName = tableName;
            bulkCopy.BulkCopyTimeout = 3000;

            var table = new DataTable();
            var props = TypeDescriptor.GetProperties(typeof(T))
                //Dirty hack to make sure we only have system data types 
                //i.e. filter out the relationships/collections
                                       .Cast<PropertyDescriptor>()
                                       .Where(propertyInfo => propertyInfo.PropertyType.Namespace.Equals("System"))
                                       .ToArray();

            foreach (var propertyInfo in props)
            {
                bulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name);
                table.Columns.Add(propertyInfo.Name, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType);
            }

            var values = new object[props.Length];
            foreach (var item in list)
            {
                for (var i = 0; i < values.Length; i++)
                {
                    values[i] = props[i].GetValue(item);
                }

                table.Rows.Add(values);
            }

            bulkCopy.WriteToServer(table);
        }
    }

在我的例子中,我从 15-20 分钟插入到不到一分钟。

关于c# - 内存泄漏 Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11450917/

相关文章:

c# - .Include() 与 .Load() 在 EntityFramework 中的表现

entity-framework - 如何通过 EF 4.1 中的 dbcontext 实体进行 foreach?

c# - 如何打开 NavigationController root 并传递一个值?

c# - 使用 closedXML 和 C# 将一系列单元格值放入列表中

.net - WPF 按钮样式触发器

c# - 使用可选参数从 F# 对象在 C# 中创建对象

c# - 将此 C# 代码转换为 VB.NET

c# - 计时器占用内存(每秒3MB)

c# - 如何加密用户的用户名和密码?

c# - 如何一次异步读取标准输出流和标准错误流