开始使用Azure功能
Azure函数是一种云原生设计策略,允许提供和执行一段代码,而不需要网络服务器或服务器基础设施设置。
C#、Java、JavaScript、TypeScript和Python只是与Azure函数集成的几种语言。
Azure函数是一个无服务器计算平台,它简化了云中少量代码或函数的执行。因此,它提高了我们的开发效率。
只编写手头任务所需的代码,而不考虑程序的其他部分或操作所需的基础设施。
本文解释了什么是Azure函数以及如何在C#编程语言中利用它们。
优点
- Azure函数很简单,不需要服务器。
- 编写和部署Azure函数要容易得多。
- Azure函数的执行是在事件发生时启动的。
- Azure函数不需要任何基础设施,也不需要任何维护。
- 使用Azure界面和浏览器,我们可以创建、测试和部署Azure函数。
- 对Azure功能的升级很简单,对网站的其他元素没有影响。
- Azure函数使用行业标准与其他API、数据库和库集成。
- 因为Azure函数是按需计算的,所以当执行请求的数量增加时,它们会扩大规模,而当请求的数量减少时,它们会缩小规模。
前提条件
- 具备使用Visual studio 2019和SQL数据库创建器的背景信息。
- 下载[Visual studio 2019]以编译Csharp代码。
- 有一些关于SQL数据库和连接的知识。
- 为了执行SQL命令,使用SQL编译器。对于我的情况,我使用[oracle终端在线]来执行命令。
如何设置Azure函数
为了建立Azure函数,我们将使用Visual Studio。在Visual Studio中,打开Blazor应用程序并创建一个新项目。然后,在项目模板页面上选择Azure函数。

选择Azure函数模板后,点击下一步。你需要为你的功能应用命名,并为Visual Studio项目选择一个操作位置。

下面的图片描述了Visual Studio中对Azure函数应用的众多触发器。

我们可以看到,每个触发器都有不同的作用。我们将利用HTTP触发器,它在发送HTTP请求的任何时候都会触发。点击创建按钮来创建应用程序。
下面是我们的函数的完整代码的一个例子
using System;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace HelloFunction {
public static class Function1 {
[FunctionName("Function1")]
public static async Task < IActionResult > Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { // HTTP trigger is executed whenever we make an HTTP request.
log.LogInformation("C# HTTP trigger function processed a request."); //This trigger causes the function to run.
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name) ?
return new OkObjectResult(responseMessage);
}
}
}
上述代码中的每个触发器都提示函数的运行。一个函数只会有一个触发器,并且只有一个目的。例如,当我们发起一个HTTP请求时,HTTP触发器将执行,导致我们的函数运行。
输出。

实体模型和数据库模式
数据库模式代表了一个关系数据库的全部或部分的逻辑设置。我们可以直观地表示数据库模式,也可以将其作为一系列控制数据库的公式,即integrity constraints 。
完整性约束是限制数据库潜在状态的机制。例如,如果我们考虑一个数据库的雇员,我们不希望有两行是同一个人。因此,根据完整性约束,employee ID在表employee的所有行中必须是唯一的。
术语entity data model ,指的是定义数据结构的概念,无论其存储方式如何。该模型使用三个基本概念描述数据结构:实体类型、关联类型和属性。
下面是雇员表模式的例子。
CREATE TABLE Employee
(
Id int IDENTITY (1,1) PRIMARY KEY,
Name nvarchar(60)NOT NULL,
Designation nvarchar(60) NOT NULL,
Town nvarchar(60) NOT NUll
);
在上面的代码中,我们在将要使用的数据库中为雇员创建一个表。

创建一个文件夹,并将其命名为My_Model。在这个文件夹中,创建一个名为Employee 的类。你可以使用一些属性来使你的实现更简单。
下面是一个例子。
namespace API_EFCore_AzureFunctions.My_Model
{
public class Employee //creating our class (employee)
{
public int IdNumber {get;set;}
public string Name {get;set;}
public string Apointment { get; set;}
public string Town {get; set;}
}
}
之后,我们将不得不把DatabaseContext 类添加到我们的项目中。DatabaseContext 允许我们使用应用程序来访问由我们的模型生成的数据库表。
创建一个名为AppDatabaseContext 的新类,并添加下面的代码片段。
using Microsoft. Entity FrameworkCore;
namespace API_EFCore_AzureFunctions.model
{
public class AppDataBaseContex:DataBaseContext //creating app databasecontext to define our Databasecontext.
{
public class AppDataBasebContex(DataBaseContextOptions<AppDataBaseContext>options)
:base(options)
{
}
public DataBase<Employee> Employee {get;set;}
}
}
上面的代码解释了我们如何创建数据库上下文以访问数据库中的表。
设置连接
要在Solution Explorer ,你需要右键单击Reference 或一个项目,然后选择管理NuGet包。
如下图所示,我们将使用Nuget包管理器或包管理器控制台安装所需的包。

Visual studio在浏览选项卡中显示来自选定来源的包。使用搜索框来搜索特定的包。安装按钮以及版本选择下拉菜单应该被启用。
初始化依赖注入
为了给我们的函数应用程序设置依赖注入,我们使用Assembly的FunctionsStartup 功能来定义一个启动类,该类将在函数应用程序启动时运行。在这个派生于Functions Startup的类中,我们将重写Configure函数。
通过在服务中注册一个DbContext ,我们可以从配置中获得SQL连接字符串,并将AppDbContext 注入我们的方法中。创建一个名为Startup.cs 的类。
using API_EFCore_AzureFunctions.Model;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(API_EFCore_AzureFunctions.Startup))] // Indication of a startup class used to run tje function app start.
namespace API_EFCore_AzureFunctions
{
public class Startup : FunctionsStartup // Integrates injection's dependency
{
public override void Configure(IFunctionsHostBuilder builder)// Configuration retrives the sql connection.
{
string connectionString = "Data Source=Server Name;Integrated Security=true;Database=Database Name";
builder.Services.AddDataBaseContext<AppDataBaseContext>(
options => SqlServerDataBaseContextOptionsExtensions.UseSqlServer(options, connectionString));
}
}
}
代码显示了我们如何在app函数中设置依赖注入,我们将使用汇编上的函数启动属性来表示一个将运行app启动函数的类。
将DbContext注入到一个函数中
因为有了依赖注入,我们现在可以在类中声明我们的函数,并将依赖注入到其构造函数中。首先,打开Function1.cs 文件,注入我们的依赖关系。
我们将打开我们的函数,如下图所示。
#region Property
private readonly AppDataBaseContext _appDataBaseContext;
#endregion
#region Constructor
public Function one (AppDataBaseContext appDataBaseContext)
{
_appDataBaseContext = appDataBaseContext;
}
#endregion
我们将使用上面的代码来注入类的依赖关系。
实现函数
在下面的例子中,我们将在实现函数时使用五个函数。
CreateEmployee- 将雇员信息保存到数据库中。GetEmployees- 从数据库中获取所有雇员的列表。GetEmployeebyId- 使用雇员的ID获得雇员记录。UpdateEmployee- 更新数据库中的雇员信息。DeleteEmployee- 删除数据库中的雇员记录。
1.1.CreateEmployee
#region Create Employee
[FunctionName("CreateEmployee")] // Here we create a new function employee
public async Task<IActionResult> CreateEmployee(
[HttpTrigger(AuthorizationLevel.Anonymous, "save", Route = Route +"/Uplode")]
HttpRequest req, ILogger log)
{
log.LogInformation("How we can get a new employee list"); //Saves employee information in the database
variable requestBody = await new StreamReader(req.Body).ReadToEndAsy();
variable input = JsonConvert.DeserializeObject<Employee>(requestBody);
variable employee = new Employee
{
Name = input.Name, Designation = input.Designation,City= input.City
};
await _appDataBaseContext.Employee.AddAsync(employee);
await _appDataBaseContext.SaveChangesAsync();
return new OkObjectResult(new
{
Message = "Sucessfull ,our record is saved", Data = employee
});
}
#endregion
上述代码在创建的数据库中添加新的雇员。
2.GetEmployee
#region Function Get Employees
[FunctionName("All employees are got")]
public async Task<IActionResult> GetEmployees(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
HttpRequest req, ILogger log)
{
try //This checks for any exceptions that may occur.
{
log.LogInformation("Getting Employee list items");
return new OkObjectResult(await _appDataBaseContext.Employee.ToListAsync());
}
catch (System.Exception) // Handles any exceptions that may occur.
{
throw;
}
}
#endregion
行代码[FunctionName("GetAllEmployee")] ,用于为函数属性添加一个名称
代码为[public async Task<IActionResult> GetAllEmployees] 的行用于定义一个函数的方法
代码为[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] 的一行被用作HTTP触发器的属性。
-
授权级别:授权密钥确保你的HTTP触发器是Azure函数。有三种类型的授权级别。
-
匿名:不需要密钥
-
函数:你将需要一个特殊的功能密钥。如果没有提供值,这就是默认值。
-
管理员:你将需要一个主密钥。
-
路由:它指定了端点的路由模板。
API/FunctionName>是路由的默认值。 -
方法:这是为函数定义HTTP动词的地方。
{
try
{
log.LogInformation("Getting Employee list items");
return new OkObjectResult(await _appDataBaseContext.Employee.ToListAsync());
}
catch (System.Exception)
{
throw;
}
上面的代码是getEmployee 函数的一部分,它添加了一个try-catch块来管理异常,并从数据库中检索所有的雇员信息。
3.GetEmloyeebyld
#region Get Employee Based on Employee Id
// Get employees by querying with their ID
[FunctionName("GetEmployeebyId")]
public async Task<IActionResult> GetEmployeebyId(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "{Id}")]
HttpRequest req, ILogger log, int Id)
{
try // This checks for any exceptions that may occur.
{
var result = await _appDataBaseContext.Employee.FindAsync(Id);
if (result is null)
{
log.LogInformation($"Item {Id} not found");
return new NotFoundResult();
}
return new OkObjectResult(result);
}
catch (System.Exception) // Handles any exceptions that may occur.
{
throw;
}
}
#endregion
上面的代码片段根据员工的ID获得任何员工的记录。
4.UpdateEmployee
#region Update Employee
// Updates the employee data changes and modifications.
[FunctionName("UpdateEmployee")]
public async Task<IActionResult> UpdateEmployee(
[HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = Route +"/Update")]
HttpRequest req, ILogger log)
{
log.LogInformation("Updating a new employee list item"); // Updates any changes of the employee.
variable requestBody = await new StreamReader(req.Body).ReadToEndAsync();
variable updated = JsonConvert.DeserializeObject<Employee>(requestBody);
variable employee = await _appDataBasbContext.Employee.FindAsync(updated.Id);
if(employee is null)
{
log.LogError($"Item {updated.Id} not found"); // If the employee is empty, we get an error message.
return new NotFoundResult();
}
if(!string.IsNullOrEmpty(updated.Name) && !string.IsNullOrEmpty(updated.Designation)) // An update is assigned if the employee's data is empty.
{
employee.Name = updated.Name; employee.Designation = updated.Designation;
employee.Town = updated.Town;
}
_appDataBaseContext.Employee.Update(employee);
await _appDataBaseContext.SaveChangesAsync();
return new OkObjectResult(new { Message = "Successful, the record was updated", Data = employee });
}
#endregion
上面的代码片段更新雇员的详细信息。
5.删除雇员
#region Delete Employee
// Deletion of the employee record from the database.
[FunctionName("DeleteEmployee")]
public async Task<IActionResult> DeleteEmployee(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "DeleteEmployee/{Id}")]
HttpRequest req, ILogger log,int Id)
{
log.LogInformation("The new employee list item update");
var employee = await _appDataBaseContext.Employee.FindAsync(Id);
if (employee is null)
{
log.LogError($"Item {Id} not found");
return new NotFoundResult();
}
_appDataBaseContext.Employee.Remove(employee); // Removes the record from the database.
await _appDataBaseContext.SaveChangesAsync();
return new OkObjectResult("Deleted, our record deleted successfully");
}
#endregion
上面的代码片段从数据库中删除了雇员的详细资料。
最后,我们能够实现所有的代码修改。首先,运行应用程序,检查Postman中的所有方法是否按预期工作。Azure Functions使用存储仿真器来获取终端上的响应。
总结
本教程介绍了如何使用Azure Functions开发无服务器API,并使用Entity Framework核心依赖注入与数据库集成。