是否保留对实体框架对象的字符串属性的引用,以防止GC收集它?

时间:2018-08-22 11:50:43

标签: c# entity-framework garbage-collection

我使用实体框架从MySQL数据库中加载条目,并创建一个新对象,在该对象中,我将数据库对象的字符串属性发送到构造函数中,并返回新对象(不直接引用任何数据库类)。

运行内存分析器时,我看到这些数据库实体负载保存在内存中。这是正确的还是有什么办法可以解决这个问题?

var eoList = new List<EnterpriseObject>();
using(var context = new DatabaseContext())
{
    var infos = context.tableName.Where(dbObject => dbObject.Date > DateTime.UtcNow).ToList();

    foreach (var dbObject in infos)
    {
        IEnumerable<SomeEnum> enums = dbObject.enumStrings.Select(enumString => enumString.ToSomeEnum()); // Added in edited, as this was the problem, this IEnumerable was a property in the EnterpriseObject and somehow kept references to the DbObjects. Changing the property to a List<SomeEnum> fixed my problem.
        var entepriseObject = new EnterpriseObject(dbObject.Name, dbObject.Date, enums);
        eoList.Add(enterpiseObject);
    }
}
return eoList;

只要引用了“ eoList”对象,上面的代码是否会将所有引用实际上保存在“信息”中?

如果是这样,是否有更好的方法来避免此问题?

Tomas

编辑:对于任何其他正在解决此问题的人,请检查我添加的代码行,即问题所在。

1 个答案:

答案 0 :(得分:3)

假设.Name.Date返回令人惊讶的类型 1 ,那么不,您的EnterpriseObject不知道这些值来自{{1} },并且不会(让自己)保持它们的生命。

我希望一个好的内存分析器可以告诉您对象是如何植根的,即“是什么使该对象保持活动状态?”。如果没有,则可以进行内存转储并使用WinDbg / SOS回答相同的问题。不要推测有关根源可能是什么。

dbObjectWinDBgSOS上进行搜索可能会为您带来一些结果,尽管大约10年左右没有人写任何新文章。对于Visual Studio,还有一个gcroot看起来不错,但我自己还没有尝试过。


1 即令人惊讶地发现VisualSOS.Extension返回Date,并且该类型还支持从其自身到this的隐式转换,从而DateTime lambda可以编译:-)