所有职位由yabo官网

在运行时在Azure上迁移EF核心的快速提示

关于我的EF Core 2 Pluralsight入门课程的一个问题是:

嗨,朱莉
谢谢你的课程。我有个问题。请您建议将代码首次迁移部署到生产数据库(Azure)的最佳做法是什么?我的意思是我创造了
asp.net使用代码优先迁移方法的核心MVC和EF.core应用程序。在部署到Azure之后。如果我更改代码优先方法中的任何模式,如何更新生产数据库中的模式(而不丢失生产数据库中的数据)

我对一些我认为值得在课程讨论之外分享的想法的回应。(请注意,这只是高级别)

为了简单的解决,我使用的一个路径是在启动时调用database.migrate。VS发布工作流有一个选项,您可以在发布应用程序时选中该选项以应用迁移。您可以在MS文档中看到将aspnet核心应用程序部署到Azure:

或者,您可以在program.cs文件中以编程方式进行迁移,该文件将执行任何必要的迁移。我的A中有一个这样的例子2019年4月《MSDN杂志》文章。如果你需要更健壮的,然后,您可以使用EF核心迁移生成脚本(可能是幂等脚本),然后将它们包含到您的更新中,并使用可以应用这些脚本的工具。如果你使用红门工具,也许他们SQL更改自动化工具。另一种类型的工具是像FlywayDB (飞行路线)或LiquidBase。我用过集装箱的Flyway。这是我最近在一次会议上使用它的演讲:LY/30AHGAR

发布一个包含VS2017机密的单一Image Docker容器并在Azure上运行它

(事先书面,但在5月2日相关文章最终发表时,该论文才得以发表。)

我刚刚完成了一个由三部分组成的系列文章,内容是构建一个容器化的ASP.NET核心API,该API使用EF核心进行数据持久化。所有这些都是在VS2017中完成的,我利用了Docker的VS2017工具。

该系列文章将于今年4月出版。5月和6月出版的《MSDN杂志》。

第1部分:码头集装箱化应用程序中的ef核心,2019年4月

第2部分:码头集装箱化应用程序中的ef核心,2019年5月

但是我没有足够的空间来包含部署我写的应用程序的重要任务,虽然我很努力去做。好,部署非常简单,但是需要执行一些新步骤来处理存储密码,以便连接到我的Azure SQL数据库。我将在这篇博文中介绍这些步骤。

我的API使用EF核心并以一个Azure SQL数据库为目标。无论我在本地调试IIS还是Kestrel,在Docker容器内进行本地调试或从服务器或云运行应用程序,我总能访问那个数据库。

这意味着我有一个要处理的连接字符串,但我想对密码保密。

解的结构在这里。我的ASP.NET核心API项目是DataApidocker。因为我使用Docker工具添加容器编排,我在解决方案中还有一个文件夹用于Docker Compose。

形象

我将在本文的第2部分(2019年5月的一期)中详细介绍,但底线是在docker-compose.yml文件中使用docker环境变量。

版本:“3.4”

服务:
dataapidocker:
图片:$Docker_Registry-DataApidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
-布兰达

在环境映射中,我有一个序列项,其中定义了DB_PW键,但没有包含值。因为那里没有价值,Docker将查看主机的环境变量。因为我只是在调试,我在我的系统上创建了一个临时环境变量,其值为密码,当我调试或运行VS2017的应用程序时,将找到password变量。该环境变量被传递到正在运行的容器中,我的应用程序具有读取该变量的代码,并将该密码包含在连接字符串中。

所以它是独立的,漂亮和整洁。

将图像发布到Azure的ACI注册表

一旦你的应用程序运行,是时候发布它了。但我们用的是Docker,所以你不发布应用程序,但是可以为你运行应用程序的docker图像。Docker工具也将在这方面提供帮助。

右键单击项目并选择“发布”。

形象

然后您将需要创建一个发布概要文件。这个配置文件的一部分是选择发布图像的位置。这里你有选择。我有一个Visual Studio订阅,如果我想要,可以将它发布到一个Azure容器注册表,或者发布到Docker Hub或其他注册表。

形象

我这篇博客文章的目标是将图像放到Azure容器注册表中,所以这是我的选择。您的Azure帐户中可以有多个容器注册。您可以在一个注册表中存储任意数量的图像。好,可能存在技术或财务限制,但关键是,一个注册表中可以有多个图像。我在这里不是要就如何管理azure财务提供建议,如何完成任务。

这是我让发布工具为我创建的注册表的概述页面。我圈出了链接,以查看可以访问您的图像的存储库。

形象

你可能有一个特定图像的不同版本所以每个"set"是一个不同的存储库。我有三个储存库,我一直在试验。

形象

DataAPI只有一个图像,发布工具自动将其标记为“最新”给我。我可以在不同的标签下有其他版本。

回到Visual Studio,在浏览了发布工具关于创建新存储库的问题之后,最后一步是进行发布,发布将构建图像并将其推送到目标存储库。请记住,您希望将VS2017设置为运行版本构建,不是调试构建。

如果这是您第一次将此图像推送到存储库,该工具还将推送应用程序DockerFile中列出的ASP.NET核心SDK和运行时映像。

我很惊讶看到这个,想知道为什么Azure不只是从Docker Hub上获取它们,为什么我要直接上传那些大文件。当然,我在推特上表达了我的困惑:

故事还有很多,但它超出了我在这里的目标范围。

这个注册表的一个很酷的功能是您可以右键单击并运行一个图像。如果你不想安排一些图像,这很好,而且与我的情况相匹配。这个映像是独立运行的。

右键单击图像并选择“运行实例”。Azure将创建一个容器并将其作为Azure容器实例。尽管首先需要为实例定义规范。

形象

这有点不可思议,因为如果容器是一个简单的应用程序,您不必创建和管理一个虚拟机来运行它。

容器实例的环境变量如何?

实例将运行,但是需要从Azure SQL数据库读取的杂志控制器将失败,因为我们没有提供容器期望通过主机的环境变量提供的密码。所以为了我的形象,右键单击并运行还不够。

在这里我要读很多书,研究和实验,直到我找到解决方案。(请记住,如果我在自己设计的虚拟机上运行此程序,当您手动调用docker run时,只需传入变量即可。)

有两种方法可以为容器实例提供环境变量。

一,通过入口,表示不是右键单击图像,首先,您需要在Azure中创建一个新的容器实例并指向该映像。此路径允许您在配置中最多分配3个环境变量:
形象

使用动态变量传递到容器中

我将进行第一次传递,创建一个动态变量以传递给environmentvariable。然后我将向您展示如何使用Azure密钥库

EnvironmentVariable需要一个散列表。

创建一个新的变量(我将称之为envvars,以纪念我学习到的资源),并分配一个键值对:

$ envVars = @ {' DB_PW ' = ' eiluj '}

另一个棘手的部分是提供访问注册表中映像的凭据。在使用门户创建容器时,我们不必这样做,因为我们已经提供了它们。但现在我需要提供它们。

您需要从存储库中获得用户名和密码:

然后,可以使用PowerShell根据密码创建安全字符串,然后使用该安全字符串和用户名创建PowerShell凭据对象。

提示:如果您有多个订阅,确保指向的是目标资源组所在的位置。

提示:在云shell中可以做的一件很酷的事情是,键入dir列出您的订阅,然后使用cd进入正确的订阅!结帐PowerShell Cloud Shell快速启动详情

小贴士:如果像我一样,为了体验因果关系,你把数据库搞得一团糟,记住在我的示例代码中,数据库在应用程序启动时迁移。在容器中包含它的情况下,这意味着当容器实例运行时。如果你运行容器,然后删除数据库,在容器再次旋转之前,您不会再次看到数据库。停止和重新启动具有相同的效果。当然,这只是为了测试一下,不生产!再一次,有件事让我困了一个多小时,直到我有了一个“啊哈”的时刻。

创建一个密钥库并添加我的密码

关于我即将举行的交付敏捷会议的视频

下周我将在敏捷联盟技术会议上发言,亚博国际网页在田纳西州纳什维尔实现敏捷。我的演讲题目是“用Docker开发和测试数据库的敏捷性”。我和田径运动主席理查德·血清素谈了这个话题。

Julie Lerman Deliver:2019年敏捷采访Richard Serateryabo官网敏捷联盟维米欧

链接到我最近的ddd+efcore内容

我所创建的各种文章和视频的聚合时间已经足够长了,其中包含了有关ef核心支持如何将域模型直接映射到关系数据库的课程,这些支持已经得到了改进:


关于docker- composition中的env文件的一个小教训

最近我和Docker一起工作了很多,学习学习。我已经为我的MSDN Mag数据点列那将在四月份推出,2019年5月和6月发行。我还有另一篇裕固族博客文章,我将在五月的文章中发表。我在研究其他人。

我研究了Docker环境变量以及将它们输入Docker映像或容器的不同方法。

我的docker compose文件引用了一个名为db_pw的环境变量,但没有指定其值。

dataapidocker:
图片:$Docker_Registry-DataApidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
——DB_PW

Docker将从主机读取环境变量以发现该值。

但这是一种痛苦。我没有在开发机器上永久性地存储db_pw,必须经常记住设置它。埃尔顿斯通曼(来自Docker)说,我应该“真正”考虑使用Docker env文件功能。这允许您在环境文件中设置变量,并让docker-compose文件从中读取。我可以把这个特殊的文件放在源代码控制之外。(我总是担心!)

我首先跟踪显示使用名为anything.env文件的文档。我创建了一个名为hush-hush.env的文件,在其中我指定了变量。这是文件的全部内容:

DB_PW = thebigsecret

然后在Docker Compose中,在服务中,env_文件标记允许您指向它。甚至可以删除YML文件中的环境标记。

dataapidocker:
图片:$Docker_Registry-DataApidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
env_file:
- HuSH HuS.Env

这很管用。我的应用程序能够在代码中发现环境变量。

但后来我改进了我的解决方案,为我的数据库使用另一个容器。主容器依赖于新的MSSQL容器。而MSSQL容器要求我将数据库密码作为一个环境变量传递。因为db_pw已经存在,通过替换(通过花括号),我可以很容易地做到这一点。这是新的Docker撰写文件:

版本:“3.4”
服务:
dataapidocker:
图片:$Docker_Registry-DataApidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
env_file:
- HuSH HuS.Env
依赖性:
-DB
分贝:
图片:mcr.microsoft.com/mssql/server
卷:
-mssql服务器julie data:/var/opt/mssql/data
环境:
sa_密码:“$db_pw”
接受“Y”
端口:
——“1433:1433”
卷:
MSSQL服务器Julie数据:

这里有一个操作顺序的问题。当我构建Docker撰写文件时,它抱怨DB U PW不可用,我的应用程序出现故障。DB服务未获取my hush-hush.env文件的内容。我尝试了很多方法,例如,将env_文件添加到db服务。最后,这是我学到的。

替换使用要求在docker-compose中定义DB_PW变量。我在主服务中添加了这个,但它并没有从hush-hush.env得到价值。

但是你可以有一个没有名字的.env文件。扩展名*是文件的全名。Docker-compose将尽早读取该文件,并提供从.env文件到声明的DB_PW的值。然后所有的碎片都到位了。mssql容器以DB_PW的值作为其环境变量展开。我的应用程序代码能够读取docker为自己的任务传递到运行容器中的环境变量。

最后一个docker-compose.yml文件如下:

版本:“3.4”
服务:
dataapidocker:
图片:$Docker_Registry-DataApidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
——DB_PW
依赖性:
-DB
分贝:
图片:mcr.microsoft.com/mssql/server
卷:
-mssql服务器julie data:/var/opt/mssql/data
环境:
sa_密码:“$db_pw”
接受“Y”
端口:
——“1433:1433”
卷:
MSSQL服务器Julie数据:

它依赖一个名为“.env”的文件定义了变量键值对(与上面的hush-hush.env相同)。

DB_PW = thebigsecret

资源:
https://docs.docker.com/compose/environment-variables网站/

宣布:深入研究英孚核心2天研讨会

6月17日至18日,与我一起在伦敦对实体框架核心进行为期两天的深入研究。yabo官网

这是一个新添加的技能物质课程目录。因为这是一门新课程,我们希望获得关于拟涵盖主题列表的反馈。如果你有兴趣参加,您的输入将有所帮助。

主题列表在2天内是否太长?它是否涉及到你想在高级课堂上学习的内容?你可以提供反馈课程描述页

第1天:利用高级功能

  • 对EF与EF6的核心差异进行高层次的回顾
  • 实现日志记录以捕获ef core的数据库和内存中的活动。了解要捕获的不同类型的日志数据
  • 学习各种播种方法,例如通过数据库脚本,代码或使用EF Core 2.1中引入的基于迁移的播种。您还将了解每种方法何时合适
  • 在开发、源代码控制和部署期间使用迁移
  • 集成测试您的EF核心代码

第2天:软件架构中的EF核心

  • 关于存储库的争论:用于公开EF Core的存储库模式/通用存储库的优缺点
  • 设计数据层/API
  • 了解复杂的映射约定,并使用Fluent API使用自定义映射对其进行补充。
  • 性能设计
  • *附加主题*如果所有模块都涵盖了,您还将在Azure函数中查看ef core,并在Azure Cosmos DB中查看ef core(给定足够的时间)

使用MongoDB C API的一些编码模式

在2019年2月的《msdn杂志》上(利用Azure Cosmos DB的API对MongoDB进行多模型性能的研究)“我的数据点”专栏探讨了使用Azure Cosmos DB的MongoDB模型MongocSharpDriver。我首先处理MongoDB的一个本地实例,然后处理Azure实例。但是柱子有点长,所以我剪了一些多余的部分。所以我把它们放在这里,并从文章链接到这个博客文章。

在本文中,我使用imongocollection对象查询数据并将其存储到数据库中。必须为要序列化和反序列化的集合对象指定类型。在这篇文章中,我把收藏打给我的班级,例如,收藏 。还可以将集合一般地键入BsonDocument。这里有一些关于它的信息和一些代码。

将集合键入BsonDocument

映射的另一个路径是使用不依赖于特定类型的BsonDocument类型化集合对象。这将允许您拥有更多的通用方法。但它也意味着手动序列化和反序列化对象,这是很容易使用ToBsonDocument序列化:

var coll=db.getcollection(变量coll=db.getcollection)
         
          (“船”);coll.insertone(ship.tobsondocument());
         

考虑到这些文件有鉴别器,然后,您可以在查询中指定一个类型来检索特定类型,尽管,默认情况下,层次结构没有得到解释。本文引用了有关C_API多态性的文档。这是链接。检查以更详细地了解如何正确实现多态性。以下代码将仅在与配置的识别器匹配的情况下收回文档,这些识别器用于船载和退役船载到DSHIPS:

var coll=db.getcollection(变量coll=db.getcollection)
         
          (“船”);var ships=coll.asqueryable().oftype
          
           ().ToList ();var dships=coll.asqueryable().oftype
           
            ().ToList ();
           
          
         

封装MongoClient,数据库和集合

重复指定类型化集合实例,正如我在文章demos中所做的,会成为拖累。你可以提前安排,例如,在充当与数据库交互的上下文的类中,如下所示:

public class expansecontext public imongodatabase expansedb get;私人集合;公共IMongoCollection}
         
          船舶{;私人集合;公共IMongoCollection}
          
           {ExpanseDb=new MongoClient().GetDatabase("ExpanseDatabase");船只= ExpanseDb.GetCollection
           
            (“船舶”);字符=expansedb.getCollection
            
             (“船”);}}
            
           
          
         

用于插入文档的重构代码可读性更高:

私有静态void InsertViaContext () {var context = new ExpanseContext ();var ship = new ship {Name = "Agatha King"};context.ships.insertone(船舶);}

登录ef core 2.2有一个更简单的语法——更像是asp.net core

记录ef-core的内存操作和SQL操作自ef-core到来以来已经发展了几次。它利用了与ASP.NET核心使用的相同的底层功能。如果您使用的是ASP.NET核心,日志是内置的,为EF Core打开它并添加过滤非常简单。参见Shawn Wildermuth的博客文章ASP.NET核心中的EF核心日志记录

但是如果您不使用ASP.NET核心,这有点复杂。不可怕,但仍然有一些额外的工作要做。它涉及在dbContext中设置iLoggerFactory并同时定义任何过滤器。

我在之前的msdn杂志上写了一篇关于这个的文章(重点是利用ef核心日志记录的各种可用过滤器),哦,等等,今天是1月1日,所以我可以说“最后一年”。数据点–在EF核心中记录SQL和更改跟踪事件。我也在我的启动EF Core 2课程,EF核心2:映射EF核心2.1:新功能Pluralsight课程。(注意,我已经将入门课程的示例代码更新到了EF Core 2.2,并将其放在GitHub上github.com/julielerman/multiplesightefcore2getingstarted

我的文章和课程使用控制台应用程序演示EF核心行为,因此ConsoleLoggerProvider将日志记录器绑定到控制台。请注意,数据点文章包含了许多关于各种过滤类型的详细信息。因此,您可以使用下面的新语法来指定应该有一个过滤器,但是一定要阅读这篇文章来了解过滤的风格,以及根据您所做的选择,您能够看到哪些类型的细节。

但是日志API不断发展,并提供了一些与ASP.NET创建的相同的快捷方式。而ConsoleLoggerProvider已经被弃用。API不是EF核心的一部分。它是。net Core的一部分。EF核心和ASP.NET核心都使用它。

如果您使用的是EF Core 2.2,语法已经改变了(简化了),在3.0中它将变得更加流线型。

事实上,如果将前面的语法与2.2一起使用,你会得到一个关于ConsoleLoggerProvider的警告:

过时的(“此方法已过时,将在将来的版本中删除。建议的替代方法是使用loggerfactory配置筛选,并使用consoleloggeroptions配置日志记录选项。“)

作为比较,下面是一个使用旧语法打开日志记录的例子,只显示与数据库命令相关的日志,只显示标记为“Information”的消息。

EF Core 2.0和2.1逻辑

public static readonly loggerfactory myconsoleloggerfactory=new loggerfactory(new[]new consoleloggerprovider((category,level)=>category==dbloggercategory.database.command.name&&level==loglevel.information,真实)};

一旦在上下文类中定义了logger工厂字段,就告诉dbContext在配置时使用它。

protected override void onconfiguring(dbContextOptionsBuilder OptionsBuilder)var connectionString=configurationManager.connectionStrings[“wpfdatabase”].toString();optionsBuilder .UseLoggerFactory(MyConsoleLoggerFactory) .EnableSensitiveDataLogging(true) .UseSqlServer(connectionString);}

这是logger工厂的创建,它的语法有点复杂。新的API遵循了ASP.NET核心如何让您使用以过滤器为参数的addfilter方法进行过滤。不需要羔羊。另外,配置过滤器是一个单独的逻辑位,用于通知日志记录器它应该绑定到控制台。

EF核心2.2逻辑

使用EF Core 2.2,您可以在构造函数或其他方法中设置记录器工厂,只要在配置选项生成器时该工厂可用。我在一个方法中创建它然后使用那个方法作为UseLoggerFactory的参数。我仍然在过滤只显示数据库命令和标记为信息的日志详细信息。

{IServiceCollection serviceCollection = new serviceCollection ();servicecollection.addlogging(builder=>builder.addconsole().addfilter(dbloggercategory.database.command.name,loglevel.information));返回ServiceCollection.BuildServiceProvider().GetService
             
              ();}
             

然后在选项builder的useLogging方法中调用getLoggerFactory():

optionsBuilder.UseLoggerFactory (GetLoggerFactory ())

文件包和参考

为了使用addconsole()方法,你还得用Microsoft.Extensions.Logging.Console以前的consoleloggerprovider所在的包。然而,命名空间不需要using语句(就像对consoleloggerprovider所做的那样)。