我使用实体框架从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
编辑:对于任何其他正在解决此问题的人,请检查我添加的代码行,即问题所在。
答案 0 :(得分:3)
假设.Name
和.Date
返回令人惊讶的类型 1 ,那么不,您的EnterpriseObject
不知道这些值来自{{1} },并且不会(让自己)保持它们的生命。
我希望一个好的内存分析器可以告诉您对象是如何植根的,即“是什么使该对象保持活动状态?”。如果没有,则可以进行内存转储并使用WinDbg / SOS回答相同的问题。不要推测有关根源可能是什么。
在dbObject
,WinDBg
和SOS
上进行搜索可能会为您带来一些结果,尽管大约10年左右没有人写任何新文章。对于Visual Studio,还有一个gcroot
看起来不错,但我自己还没有尝试过。
1 即令人惊讶地发现VisualSOS.Extension
返回Date
,并且该类型还支持从其自身到this
的隐式转换,从而DateTime
lambda可以编译:-)>