You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Azure Functions结合EF Core实现CRUD及依赖注入问题

.NET 8 Azure Function 结合 EF Core 实现CRUD与依赖注入方案

一、基础配置与依赖安装

  • 安装必要NuGet包:
    • Microsoft.Azure.Functions.Worker.Extensions.Http(HTTP触发器支持)
    • Microsoft.EntityFrameworkCore.SqlServer(SQL Server数据库适配,若用其他数据库替换对应包)
    • Microsoft.Extensions.DependencyInjection(依赖注入支持)

二、定义DbContext

创建自定义DbContext类,映射数据库表:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    // 映射Locations表
    public DbSet<Location> Locations { get; set; }
}

// 示例实体类
public class Location
{
    public int Id { get; set; }
    // 注意:数据库允许为空的字段,实体需定义为可空类型
    public string? Name { get; set; }
    public string Address { get; set; } = string.Empty;
}

三、注册依赖注入(Program.cs)

在函数启动类中配置DbContext与其他服务:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        // 从环境变量读取数据库连接字符串
        var connectionString = Environment.GetEnvironmentVariable("SqlConnectionString");
        // 注册DbContext
        services.AddDbContext<AppDbContext>(options =>
            options.UseSqlServer(connectionString));
        
        // 若使用仓储模式,可注册仓储服务
        // services.AddScoped<ILocationRepository, LocationRepository>();
    })
    .Build();

host.Run();

四、在Function中注入并实现CRUD

通过构造函数注入DbContext,编写CRUD方法:

public class LocationFunctions
{
    private readonly AppDbContext _appDbContext;

    // 构造函数注入DbContext
    public LocationFunctions(AppDbContext appDbContext)
    {
        _appDbContext = appDbContext;
    }

    // 查询第一条数据
    [Function("GetFirstLocation")]
    public async Task<HttpResponseData> GetFirstLocation([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
    {
        var response = req.CreateResponse(HttpStatusCode.OK);
        try
        {
            // 用FirstOrDefault替代First,避免无数据时抛异常
            var firstLocation = await _appDbContext.Locations.FirstOrDefaultAsync();
            if (firstLocation == null)
            {
                await response.WriteAsJsonAsync(new { Message = "无可用位置数据" });
                return response;
            }
            await response.WriteAsJsonAsync(firstLocation);
        }
        catch (SqlNullValueException ex)
        {
            await response.WriteAsJsonAsync(new { Error = "数据库存在空值字段", Details = ex.Message });
            response.StatusCode = HttpStatusCode.BadRequest;
        }
        return response;
    }

    // 创建数据
    [Function("CreateLocation")]
    public async Task<HttpResponseData> CreateLocation([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
    {
        var location = await req.ReadFromJsonAsync<Location>();
        if (location == null)
        {
            var badResponse = req.CreateResponse(HttpStatusCode.BadRequest);
            await badResponse.WriteAsJsonAsync(new { Message = "无效的位置数据" });
            return badResponse;
        }

        _appDbContext.Locations.Add(location);
        await _appDbContext.SaveChangesAsync();

        var response = req.CreateResponse(HttpStatusCode.Created);
        await response.WriteAsJsonAsync(location);
        return response;
    }

    // 其他CRUD方法(更新、删除)可按类似逻辑实现
}

五、SqlNullValueException问题排查与解决

该异常本质是实体非可空属性对应数据库字段为NULL,修复步骤:

  1. 检查实体类属性:数据库允许为空的字段,实体必须定义为可空类型(如string?而非string)
  2. 核对数据库表结构:确保实体非可空属性对应的数据库列已设置NOT NULL约束
  3. 优化查询逻辑:用FirstOrDefaultAsync()替代FirstAsync(),避免无数据时触发额外异常

内容的提问来源于stack exchange,提问作者Vishal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:52:47