这是如何运作的? LINQ to Entities 触发程序集的加载?
Posted
技术标签:
【中文标题】这是如何运作的? LINQ to Entities 触发程序集的加载?【英文标题】:How does this work? LINQ to Entities triggers loading of assemblies? 【发布时间】:2013-04-12 14:37:29 【问题描述】:解决方案中的项目
我有一个针对 .NET 4.5 并使用 Entity Framework 6 Alpha 3 的典型 3 层解决方案。该解决方案由三个项目组成,我们称之为:
-
实体 - 包含 EF 模型和实体定义的类库
DataAccess - 充当 UI 和数据库之间的“业务层”的类库
WinformsClient - Winforms 客户端应用程序
参考文献
WinformsClient 项目包含许多外部引用,包括对 CrystalReports DLL、其他“公司范围”程序集等的引用。
在我的 WinformsClient 中,我引用了我的 DataAccess 库。两者都使用实体库。
触发问题
我从 WindowsClient 调用 DataAccess 库上的一个方法,我们称之为GetData
。在这个方法中,创建了一个 DbContext
,执行了一些 LINQ 魔术并返回了一个 IEnumerable<T>
。
问题
现在,当我第一次调用此方法时,在调用第一个 LINQ 扩展方法时会加载许多外部程序集。这包括需要很长时间才能加载的 CrystalReports DLL。 但这些程序集都没有真正被 Entities 或 DataAccess 库引用,也不需要执行或显示数据。
事实上,当我创建一个引用 DataAccess 和实体库的单独控制台应用程序时,我可以调用 GetData
并获得我的实体列表,并且没有加载任何外部库。
我怀疑 Entity Framework / LINQ to Entities 与此有关,因为当我只是从 DataAccess 库中返回 POCO 的列表(不加载 EF)时,没有加载任何外部引用。
谁能解释这种行为?
更新
此问题可能与this question 密切相关,其中 Entity Framework 尝试加载从项目中引用的所有程序集。任何有助于我理解为什么会发生这种情况/如何影响这种情况的建议仍然受欢迎!
【问题讨论】:
延迟加载?如果您有虚拟导航属性并且每次访问尚未加载的属性时都打开延迟加载(默认情况下),EF 将访问数据库并加载实体 - 这可能会触发加载程序集,如果所需的类型尚未加载。 msdn.microsoft.com/en-us/magazine/hh205756.aspx 不要忘记数据库模型的初始化。 @Pawel 我不这么认为,因为实体模型目前非常简单(它只包含 2 个实体,不依赖于外部程序集中的任何代码),并且我没有访问任何导航属性。 我对Crystal Reports 一无所知,但我相信在需要之前您不会得到负载,对吧?那么谁在代码中引用了 CR?是否存在某些事件导致引用 CR 的代码被执行,例如数据被绑定?这是我对此的初步想法。 .NET 程序集加载 JIT,因此似乎有些东西正在引用它。如果您可以发布一些代码,可能会有所帮助。 看起来有些东西正在触发自动发现 - 尝试检查发生了什么,例如使用 procmon 并通过进程和文件操作进行过滤 - 它会枚举 *.dll(自动发现),还是会查找特定的程序集(内心深处的东西)? 【参考方案1】:问题不在于实体或数据访问层,显然,问题在于您的 WinformsClient。我的建议是您在调用GetData
方法的行设置断点,这显然在您的 WinformsClient 项目中。
从那里,进入GetData
方法并检查您的调用堆栈,也许在那里您会找到违规者。似乎调用 GetData
的方法正在被您的 WinformsClient 应用程序中的某些东西监视。 (obs:评论太长了)
【讨论】:
你是对的,它在 Winforms 客户端。但是,代码本身除了引用我的数据访问库并调用GetData
之外什么也没做。所以那里没有明显的可疑代码。请查看我的问题中的更新...以上是关于这是如何运作的? LINQ to Entities 触发程序集的加载?的主要内容,如果未能解决你的问题,请参考以下文章
如果不支持包含,您如何在 LINQ to Entities(实体框架)中执行 SQL 样式的“IN”语句?
将日期时间转换为 LINQ-to-entities 查询中的格式化字符串
LINQ to Entities 为实体的子级返回错误的 ID