是否可以构建包含用于访问SQL Server数据库的实体框架(Core或EF6)的PowerShell cmdlet?
多年来我一直在用C#编写cmdlet,但是由于似乎是程序集版本冲突,我在过去的coupla日子里试图在项目中使用Entity Framework经历了一场噩梦。
项目有三个库:
MyProject.Commands.dll
-要加载的cmdletMyProject.Lib.dll
-cmdlet使用的公共库代码MyProject.EF.dll
-仅用于实体框架。EF是分开的,因为我使用数据库优先方法(我必须对现有系统进行逆向工程,所以从数据库构建的各种.cs
模型文件位于单独的单元中,所以请保持它们的直线。
我正在Windows 10上构建所有这些文件,并且该项目仅需要在此计算机上运行。它正在与Azure云中的SQL数据库进行通信。
使用nuget添加所需的软件包之后,一切都构建良好,但是在Import-Module
上使用MyProject.Commands.dll
会得到我:
System.IO.FileNotFoundException: Could not load file or assembly \
'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' \
or one of its dependencies. The system cannot find the file specified.
打开某种绑定调试日志后,
=== Pre-bind state information ===
LOG: DisplayName = System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
(Fully-specified)
LOG: Appbase = file:///C:/Windows/System32/WindowsPowerShell/v1.0/
LOG: Initial PrivatePath = NULL
Calling assembly : Microsoft.EntityFrameworkCore.Relational, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60.
我一直无法找到System.ComponentModel.Annotation
的确切版本,但互连网中充斥着同一问题的报告。我用DLL中的AssemblyResolver尝试了各种方法,各种框架的不同版本,最终都无济于事。
最终,我发现此页面https://docs.microsoft.com/en-us/ef/core/platforms/表示任何.NET Framework版本(在.NET Core上)均不支持EF Core 3.x,但是几天前的这篇博客文章https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-3-1-and-entity-framework-6-4/表示现在毕竟受支持。
上面是一个粗略的重述,因为它是在我去计划B之前的一个很久以前(昨晚)。这太令人发疯了。
[无论是否确定EF Core都可能是未来的更好方向,我得到了VS 2019,并将整个项目重新定位到.NET Core 3.1上的EF Core 3.1。这是我对.NET Core的首次尝试。
花了一些时间来整理依赖项(包括将System.Management.Automation
换成Microsoft.PowerShell.SDK
),但最终所有东西都建立了。安装Powershell 6之后,我现在受到欢迎:
VERBOSE: Loading module from path 'D:\Dev\MyProject\MyProject.Commands\bin\Debug\netcoreapp3.1\MyProject.Commands.dll'.
Import-Module : Could not load file or assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f
7f11d50a3a'. The system cannot find the file specified.
太棒了!
现在无法找到System.Runtime
的4.2.2.0版本,我真的很茫然。
在每个项目的生成区域bin\Debug\netcoreapp3.1\
目录中是一个*.deps.json
文件,其中列出了各种依赖关系,但对System.Runtime
的每个引用均适用于4.3.0版。
我尝试过Process Monitor,各种用于查看装配体的工具,在GAC周围闲逛。松饼。
将库保留不变,我将主要逻辑封装到控制台应用程序中,并将其编译为.EXE
。
它第一次起作用。
构建控制台应用程序的工作如此顺利的事实表明,试图在PowerShell中进行所有这些工作很可能无法解决。
一个独立的应用程序可以控制自己的依赖关系,但是构建必须在另一个程序(powershell)中托管的DLL意味着我们必须工作并很好地处理its依赖关系。
令我惊讶的是,[[可能可以仔细分析现有的pwsh.exe
(即Powershell 6)并找到其确切的依存关系集,然后寻找恰好与之匹配的EF Core版本。 。这似乎没有希望,但可能会很脆弱。
我讨厌我的生活。我注定要失败吗?
[EDIT要清楚一点,我不是要在PowerShell script
中使用实体框架,我不确定自己是否想要。它在C#DLL中使用EF,它可以以编程方式完成与数据库的所有繁重工作]我已经有相当合理的直接SQL调用(同样,在C#中),效果很好,但是我有数十个表可以进行反向工程,并且让EF通过构建模型和所有简单的操作为我做到这一点非常有帮助-访问代码。 foreach (var item in DbContext.Employee
.Where(x => x.Salary > 1000.00)
.OrderBy(x => x.EmployeeId))
{
do something
}
[Entity Framework程序包从数据库中的定义构建了Employee
类(尽管您也可以使用代码优先方法),而以上内容实际上是我必须编写的唯一代码。我很想在PowerShell cmdlet中使用EF很长时间了,但从未使其能够正常工作。
关于实体框架的不错的读物:https://docs.microsoft.com/en-us/ef/core/
如果搜索时间足够长,您将遇到一些解决方案,例如人们编写代码以进行依赖性遍历DLL的多层结构,然后依次导入每个dll,直到全部导入为止。老实说,仅编译并调用一个exe似乎对我来说就更整洁和可支持了。
我们经常使用EF进行DB-First支架,我们还面临着以可支持的方式向客户交付反向工程应用程序和代码的挑战。最后,我们接受了最干净的方法是在Docker容器中使用基于EF Core + .Net Core的MVC Web项目。它们是跨平台的,只有一种语言被整齐地打包。
为了简单回答您的问题,是的,当我们每个人开始编写代码时,我们就注定了永恒。