【问题标题】:Entity Framework ObjectSet in PowershellPowershell 中的实体框架对象集
【发布时间】:2014-04-01 04:07:50
【问题描述】:

我在 Visual Studio 中创建了一个包含我的实体框架 ObjectContext 的 DLL。我正在尝试从 PowerShell 访问其各种 ObjectSets。我这样做是因为我有一些从 Web 服务中提取的 XML 文件,并且我想使用 PowerShell 的 xml 功能(自动属性生成、非致命 $null 评估)来将传入的 xml 值映射到实体不得不使用 C# Xml 类。基本上我的 PowerShell 脚本是一个数据加载器。

我能够很好地创建和实例化 ObjectContext。我可以使用 $myObjectContext | Get-Member -MemberType Property 查看所有属性。但是,我无法理解何时从查询返回到 ObjectSet 的确切项目。

我知道在 Linq-to-Entities 中存在延迟加载,并且仅在枚举集合时才加载对象。我试过显式调用扩展方法,但看起来 PowerShell 不提供 lambda 表达式支持。

这是我的问题。我怎么知道我的查询何时会被显式枚举?例如,这里是属性之一(定义为ObjectSet<VehicleType> VehicleTypes { get; })。

PS> $myObjectContext.VehicleTypes

产生以下错误,我将其标记为 (TheError) 以供将来参考:

format-default : Exception has been thrown by the target of an invocation. + CategoryInfo : Not Specified: (:) [format-default], TargetInvocationException + FullyQualifiedErrorId : System.Reflection.TargetInvocationException

但是,PS> $myObjectContext.VehicleTypes | Select-Object VehicleTypeID

产生正确的输出(VehicleTypeID 表)

但是,PS> $myObjectContext.VehicleTypes | Select-Object * 给出的 TheError 如上所述。

PS> $myObjectContext.VehicleTypes | Sort-Object 似乎总是枚举集合,这是可以理解的,因为它需要查看所有元素来比较它们。

我应该注意,在集合被枚举一次之后,调用PS> $myObjectContext.VehicleTypes 不会给出上面的 TheError - 它会完全按照您的方式显示集合,除了。这确实很奇怪,但我认为这与延迟加载有关(这就是我在上面提到它的原因)。

其他人能否向我确认/解释这种行为,或许可以给我一些关于将实体框架与 PowerShell 结合使用的最佳实践的建议?

另外,如果我执行PS> $myObjectContext.VehicleTypes | Where-Object {$_.VehicleTypeID -eq $vehicleTypeId} 之类的操作,它会足够聪明地执行该查询服务器端,还是会从数据库中获取所有记录并仅返回我正在寻找的记录。如果情况是后者,我想我可能会坚持使用 C#(其不太友好的 xml 语法)进行数据访问。

【问题讨论】:

  • 出于好奇,如果你运行这个会发生什么:"$myObjectContext.VehicleTypes | write-host" 与这个:"$myObjectContext.VehicleTypes | out-host"
  • $myObjectContext.VehicleTypes | Write-Host 不会产生上述错误。相反,它会将每个对象的类型(实际上是完整的命名空间和类似 MyNamespace.VehicleTypes 的类型)写入屏幕,而不是实际的对象值。 $myObjectContext.VehicleTypes | Out-Host 产生如上所述的错误。感谢您的提示。

标签: entity-framework powershell data-access-layer


【解决方案1】:

我可以告诉你,这段代码执行的枚举: PS> $myObjectContext.VehicleTypes | Where-Object {$_.VehicleTypeID -eq $vehicleTypeId} 都是客户端。

如果要执行本机筛选,则需要创建一个 cmdlet 来访问数据,或者创建一个支持本机筛选器的提供程序。

【讨论】:

  • 我担心这一切都发生在客户端,经过您的评论和我自己的思考,这完全有道理。使用 Linq 进行服务器端查询的原因是 MS 构建了 Linq-to-Entities,它构建了自定义表达式以在服务器端执行。
  • 试图编辑我上面的评论,但 5 分钟过去了。无论如何,让我澄清一下我想说的话。我的理解是,使用 Linq-to-Entities 在服务器端进行查询的原因是 API 构建了自定义表达式和表达式树,这些表达式和表达式树评估并简化为在服务器端执行的适当 SQL 语句。
  • 根据您的写入主机/主机外实验,这绝对是 powershell 格式化子系统内部的东西。请务必将其归档到 connect.microsoft.com/PowerShell
【解决方案2】:

我意识到有点晚了,但 TheError 可能是由于 powershell.exe 运行 .net v2.0。请参阅 cmo999 的answer,以及我自己的类似question

可以通过添加/修改 powershell.exe.config 将 powershell.exe 配置为在 .net 4.0 下运行,如上面链接中的 cmo999 所述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多