在Docker中运行SQLServer ASP.NET应用

简介: 本文介绍了如何在Docker中运行.NET程序并访问SQL Server云数据库。

logos

云栖社区的文章在阿里云上运行ASP.NET Docker应用一文和大家探讨了如何在Docker中运行ASP.NET应用。本文是上一篇文章的续篇,讨论如何让应用访问SQLServer数据库。

创建SQLServer数据库

我们首先在阿里云上开通一个SQLServer服务器实例,创建用户user1

user

创建一个名为Blog的数据库,并授权user1能够访问数据库。为数据库开通外网访问,获得数据库外网访问地址。

database

所有这些操作都能够在控制台完成,如果你想进入SQLServer的控制台,可以点击上图的登录数据库进入数据库的访问界面:

dbmgmt

上图显示的内容示例程序运行完成后的结果,现在不用手工创建数据库表,我们会利用Entity Framework的数据库Migration功能初始化数据库。

至此你应当有如下数据库访问信息,记录下这些信息以备下文的程序使用。

  • 数据库地址
  • 端口号
  • 用户名
  • 密码

引入ORM框架Entity Framework

Entity Framework是.NET上的ORM框架,支持多种常见数据库,包括MS SQL Server、SQLite、Postgres等。详细信息请访问官方博客:Announcing Entity Framework Core 1.0

我们在project.json中引入Entity Framework和SQLServer。

"dependencies": {
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.0",
"Microsoft.EntityFrameworkCore.Design": {
  "version": "1.0.0-preview2-final",
  "type": "build" 
},
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0"
},

还有这一段:

"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" 
} 

执行restore命令加载所有依赖包和工具。

dotnet restore

命令完成后创建project.lock.json文件,不要手工更改这个文件,每次引入新的依赖后请再次执行Restore命令。

数据模型和数据库连接

Entity Framework通过DbContext定义对数据库的访问以及对象和数据库的关系映射。我们首先创建一个新C#文件,命名为Model.cs。

在Model.cs中创建一个类BloggingContext继承自DbContext。

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var serverAddress = Environment.GetEnvironmentVariable("SQLSERVER_ADDRESS");
        var serverPort = Environment.GetEnvironmentVariable("SQLSERVER_PORT");
        var userName = Environment.GetEnvironmentVariable("SQLSERVER_USERNAME");
        var password = Environment.GetEnvironmentVariable("SQLSERVER_PASSWORD");

        var connection = string.Format("Server={0},{1};Database=blog;User Id={2};Password={3};",
        serverAddress,serverPort,userName,password);
        optionsBuilder.UseSqlServer(connection);
    }
}

OnConfiguring方法里定义如何访问数据库。从环境变量中读取值构建connection字符串,然后调用optionsBuilder的UseSqlServer方法建立和数据库的连接。如何想要访问其他类型的数据库,例如sqlite,调用optionsBuilder的相应方法即可。

var connection = string.Format("Server={0},{1};Database=blog;User Id={2};Password={3};",
    serverAddress,serverPort,userName,password);
optionsBuilder.UseSqlServer(connection);

我们的示例中定义两个类,分别是博客Blog和帖子Post,在数据库中是两个不同的数据库表。每个类都只定义了属性和get/set方法。随后我们会利用Entity Framework初始化数据库。

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public string Name { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

访问数据库的代码

更改Startup.cs,加入对数据库的访问。把Startup.cs中的这一段替换:

return context.Response.WriteAsync("Hello from ASP.NET Core!");

替换的内容为:

using (var db = new BloggingContext())
{
    var result = "";
    db.Blogs.Add(new Blog { Url = "https://yq.aliyun.com/teams/11" });
    var count = db.SaveChanges();
    result += string.Format("{0} records saved to database\n", count);

    result += string.Format("All blogs in database:\n");
    foreach (var blog in db.Blogs)
    {
        result += string.Format(" - {0}\n", blog.Url);
    }                
    return context.Response.WriteAsync(result);
}

这段代码的作用是在通过创建一个Blog对象在数据库中插入一行,然后从数据库中读取并显示。

利用Entity Framework初始化数据库

运行Entity Framework工具创建一个数据库迁移脚本,并初始化数据库。

dotnet ef migrations add MyFirstMigration
dotnet ef database update

登陆到数据库中可以看到新创建的两个表BlogPost

运行

所有代码就绪后即可运行应用观察效果:

$ dotnet run
$ curl http://localhost:5000/
1 records saved to database
All blogs in database:
 - https://yq.aliyun.com/teams/11

从输出可以看到,我们的程序成功地写入数据库一条数据,然后读取数据库中的所有内容。

容器化

Dockerfile内容和helloword的Dockerfile内容一样,抄录在此。

FROM microsoft/dotnet:latest
COPY bin/release/netcoreapp1.0/publish/ /app/
EXPOSE 5000/tcp
ENTRYPOINT dotnet /app/aspnet-sqlserver.dll

创建docker-compose.yml,用于在本地Docker环境中运行:

version: "2"
services:
  aspnet-helloworld:
    image: registry.cn-hangzhou.aliyuncs.com/jingshanlb/aspnet-sqlserver
    environment:
      - SQLSERVER_ADDRESS=
      - SQLSERVER_PORT=
      - SQLSERVER_USERNAME=
      - SQLSERVER_PASSWORD=
    ports:
      - 5000:5000

填入相应的环境变量值,分别是数据库地址、端口号、用户名和密码,运行docker compose命令启动容器。

$ docker-compose up -d

用同样的方式curl访问本机5000端口,可以看到在容器中也运行正常。

部署到阿里云容器服务上

部署到阿里云上的模版内容和在本机的文件基本一致,但是有几个小的变化:

  • 利用变量名输入数据库的地址、端口、用户和密码
  • 不用将容器映射到主机500端口,利用容器服务的路由服务能力
  • 指定该服务启动两个容器

这是docker-compose-acs.yml内容:

version: "2"
services:
  aspnet-helloworld:
    image: registry.cn-hangzhou.aliyuncs.com/jingshanlb/aspnet-sqlserver
    environment:
      - SQLSERVER_ADDRESS=${SQLSERVER_ADDRESS}
      - SQLSERVER_PORT=${SQLSERVER_PORT}
      - SQLSERVER_USERNAME=${SQLSERVER_USERNAME}
      - SQLSERVER_PASSWORD=${SQLSERVER_PASSWORD}
    labels:
      aliyun.scale: '2'
      aliyun.routing.port_5000: http://aspnet-sqlserver

利用模版部署后,访问服务端点URL,可以看到如下输出:

access

讨论和总结

本文介绍了如何在Docker中运行.NET程序并访问SQL Server云数据库,利用ORM框架Entity Framework Core,我们可以很容易地对数据库进行初始化和Migration。

.NET Core应用容器化上云后可以利用阿里云容器服务的丰富功能。容器服务不但支持docker-compose模板提供的容器功能,使得本地开发的Docker镜像和编排模板可以轻松上云;更提供了灵活的部署约束描述,使得对分布式应用的部署和控制变得非常方便。

想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice

相关文章
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
781 10
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
647 23
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
322 5
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
555 2
|
监控 安全 API
Docker + .NET API:简化部署和扩展
Docker + .NET API:简化部署和扩展
193 1
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
769 6
|
监控 安全 API
最完美的扩展Docker + .NET API:简化部署和扩展
最完美的扩展Docker + .NET API:简化部署和扩展
302 0
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
432 0
|
开发者 API Windows
从怀旧到革新:看WinForms如何在保持向后兼容性的前提下,借助.NET新平台的力量实现自我进化与应用现代化,让经典桌面应用焕发第二春——我们的WinForms应用转型之路深度剖析
【8月更文挑战第31天】在Windows桌面应用开发中,Windows Forms(WinForms)依然是许多开发者的首选。尽管.NET Framework已演进至.NET 5 及更高版本,WinForms 仍作为核心组件保留,支持现有代码库的同时引入新特性。开发者可将项目迁移至.NET Core,享受性能提升和跨平台能力。迁移时需注意API变更,确保应用平稳过渡。通过自定义样式或第三方控件库,还可增强视觉效果。结合.NET新功能,WinForms 应用不仅能延续既有投资,还能焕发新生。 示例代码展示了如何在.NET Core中创建包含按钮和标签的基本窗口,实现简单的用户交互。
378 0
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
253 0