具有 Entity Framework Core 的 .Net 8 上的 Azure Functions

问题描述 投票:0回答:1

我需要使用 .Net 8 和 EF Core 创建一个 Azure Function 应用程序,我可以:

  • 从 Az 函数执行 CRUD 操作
  • 使用数据库上下文或存储库对象
  • 确保这两个对象中的任何一个都可以通过依赖注入使用。

我曾尝试寻找相同的教程或良好的工作示例,但到目前为止却空手而归。任何帮助都将非常感激。

编辑:添加错误详细信息。

我尝试了与 Vivek 相同的方法,但遇到了问题。例如,当我使用 dbContext 查询时,我无法获取数据。这是我的构造函数:

public Function1(
    ILogger<Function1> logger,
    AppDbContext appDbContext)
{
    _logger = logger;
    _appDbContext = appDbContext;

    try
    {
        var test = _appDbContext.Locations.First();
    }
    catch (Exception ex)
    {
        string message = ex.Message;    
    }
}

检查 _dbContext.Locations 的值显示以下错误:

'((Microsoft.EntityFrameworkCore.Internal.InternalDbSet<Models.Location>)_appDbContext.Locations).Local' threw an exception of type 'System.InvalidOperationException'

我在代码中看到的异常如下:

at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
   at Microsoft.Data.SqlClient.SqlBuffer.get_String()
   at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at VTEst.Function1..ctor(ILogger`1 logger, AppDbContext appDbContext) in C:\Users\.....\Function1.cs:line 22

最后,功能控制台的输出如下:

[2024-03-18T18:47:59.633Z] An exception occurred while iterating over the results of a query for context type 'VTest.AppDbContext'.
[2024-03-18T18:47:59.634Z] System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
[2024-03-18T18:47:59.635Z]    at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
[2024-03-18T18:47:59.635Z]    at Microsoft.Data.SqlClient.SqlBuffer.get_String()
[2024-03-18T18:47:59.636Z]    at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
[2024-03-18T18:47:59.636Z]    at lambda_method2(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
[2024-03-18T18:47:59.637Z]    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
[2024-03-18T18:47:59.637Z] Result: An exception occurred while iterating over the results of a query for context type 'VTest.AppDbContext'.
[2024-03-18T18:47:59.638Z] System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
[2024-03-18T18:47:59.639Z]    at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
[2024-03-18T18:47:59.639Z]    at Microsoft.Data.SqlClient.SqlBuffer.get_String()
[2024-03-18T18:47:59.640Z]    at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
[2024-03-18T18:47:59.640Z]    at lambda_method2(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
[2024-03-18T18:47:59.641Z]    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
Exception: System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
[2024-03-18T18:47:59.641Z]    at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
[2024-03-18T18:47:59.642Z]    at Microsoft.Data.SqlClient.SqlBuffer.get_String()
[2024-03-18T18:47:59.642Z]    at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
[2024-03-18T18:47:59.643Z]    at lambda_method2(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
[2024-03-18T18:47:59.644Z]    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
Stack:    at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
[2024-03-18T18:47:59.644Z]    at Microsoft.Data.SqlClient.SqlBuffer.get_String()
[2024-03-18T18:47:59.645Z]    at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
[2024-03-18T18:47:59.645Z]    at lambda_method2(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
[2024-03-18T18:47:59.646Z]    at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext().

谢谢你,

dependency-injection entity-framework-core azure-functions .net-8.0 azure-functions-isolated
1个回答
1
投票

这对我有用。 我已经使用了Http Trigger功能。

我的代码:

.csproj
:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.3" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
  </ItemGroup>
</Project>

Program.cs
:

using FunctionApp14;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using System;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.AddDbContext<TodoContext>(options =>
            options.UseSqlServer(Environment.GetEnvironmentVariable("SQL_Conn")));

    })
    .Build();

host.Run();

Function1.cs
:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;

namespace FunctionApp14
{
    public class Function1
    {
        private readonly ILogger<Function1> _logger;
        private readonly TodoContext _context;

        public Function1(ILogger<Function1> logger, TodoContext context)
        {
            _logger = logger;
            _context = context;
        }

        [Function("Function1")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            var input = JsonSerializer.Deserialize<TodoItem>(requestBody);

            _context.TodoItems.Add(input);
            await _context.SaveChangesAsync();
            return new OkObjectResult($"Welcome to Azure Functions!\nData: {input}");
        }
    }

    public class TodoItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }

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

        public DbSet<TodoItem> TodoItems { get; set; }
    }


}

INPUT

{
    "Id": 1,
    "Name": "Vivek",
    "IsComplete": true
}

OUTPUT

© www.soinside.com 2019 - 2024. All rights reserved.