简体   繁体   English

来自 Function App 的 Table Storage 的 CRUD 操作

[英]CRUD operations for Table Storage from Function App

I have a small problem.我有一个小问题。 I am trying to do a migration from Cosmos db to table storage in Azure. The problem is that I haven't dealt with table storage for a long time.我正在尝试从 Cosmos db 迁移到 Azure 中的表存储。问题是我已经很长时间没有处理表存储了。 It turned out that a large part of the packages that I used before were already out of date.原来我之前用的包有很大一部分已经过时了。 And the offical documentation does not provide the needed information.并且官方文档没有提供所需的信息。

Currently I use this method to add item:目前我使用这种方法来添加项目:

public static async Task AddDomain(CloudTable table, DomainEntity domain)
        {
            TableOperation insertOperation = TableOperation.Insert((Microsoft.WindowsAzure.Storage.Table.ITableEntity)domain);

            await table.ExecuteAsync(insertOperation);
        }

and this function App to add Domain:和这个 function 应用添加域:

[FunctionName("AddDomain")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function,"post", Route = null)] HttpRequest req,
            [Table("Domains")] CloudTable domainsTable,
            ILogger log)
        {
            DomainEntity domain = CreateDomain();
            await AddDomain(domainsTable, domain);
            return new OkResult();
        }

But when i run the function its throw Exception:但是当我运行 function 时它抛出异常:

Error indexing method 'AddDomain'

and

System.InvalidOperationException at Microsoft.Azure.WebJobs.Extensions.Tables.TableAttributeBindingProvider.TryCreate. 

I have same problems with other CRUD operations too.我对其他 CRUD 操作也有同样的问题。 Any idea what is going on?知道发生了什么事吗?

Here is how i did it last month这是我上个月做的

My service class我的服务 class

using Azure;
using Azure.Data.Tables;
using VPMS.FuncApp.EFCore.AuditSetup;

namespace VPMS.Persistence.AuditSetup;

internal class TableStorageService : ITableStorageService
{
    private readonly TableServiceClient _tableServiceClient;

    public TableStorageService(TableServiceClient tableServiceClient)
    {
        _tableServiceClient = tableServiceClient;
    }

    public async Task BulkInsert(string tableName, string partionKey, List<AuditTableStorageTable> audit)
    {
        var client = _tableServiceClient.GetTableClient(tableName);

        List<TableTransactionAction> addEntitiesBatch = new List<TableTransactionAction>();

        addEntitiesBatch.AddRange(audit.Select(e => new TableTransactionAction(TableTransactionActionType.Add, e)));

        await client.SubmitTransactionAsync(addEntitiesBatch).ConfigureAwait(false);

    }

    public async Task CreateTableIfNotExistsAsync(string tableName)
    {
        var client = _tableServiceClient.GetTableClient(tableName);

        await client.CreateIfNotExistsAsync();
    }
}

My Function App我的 Function 应用

using Microsoft.Azure.WebJobs;
using Microsoft.EntityFrameworkCore;
using VPMS.FuncApp.EFCore;
using VPMS.FuncApp.EFCore.AuditSetup;
using VPMS.Persistence.AuditSetup;

namespace VPMS.FuncApp.ArchiveAppAuditLogs;

public sealed class ArchiveAppAuditLogTimerTrigger
{
    private readonly VPMSDbContext _dbContext;
    private readonly ITableStorageService _tableStorageService;

    public ArchiveAppAuditLogTimerTrigger(VPMSDbContext dbContext, ITableStorageService tableStorageService)
    {
        _dbContext = dbContext;
        _tableStorageService = tableStorageService;
    }

    [FunctionName(nameof(ArchiveAppAuditLogTimerTrigger))]
    public async Task ArchiveAppAuditLogTrigger([TimerTrigger("%ArchiveAppAuditLogCron%")] TimerInfo myTimer)
    {
        var currentDate = DateTimeOffset.UtcNow.Date;

        var auditTable = _dbContext.Set<Audit>();

        await _tableStorageService.CreateTableIfNotExistsAsync(FuncAppConstants.AuditTableName);

        var query = auditTable.Where(w => w.CreatedOn < currentDate);

        int pageSize = 100;
        bool hasMoreRecords = true;

        for (int skip = 1; hasMoreRecords is true; skip++)
        {
            var recordsToSync = await query.Skip(0)
                                           .Take(pageSize)
                                           .ToListAsync();

            hasMoreRecords = recordsToSync.Any();

            if (hasMoreRecords is false) break;

            var groupedAuditData = recordsToSync.GroupBy(b => b.TableName).ToList();

            foreach (var groupedAuditDatem in groupedAuditData)
            {
                List<AuditTableStorageTable> auditStorageTableRecords = new();

                foreach (var auditEntry in groupedAuditDatem.ToList()) auditStorageTableRecords.Add(AuditTableStorageTable.BuilData(auditEntry));

                await _tableStorageService.BulkInsert(FuncAppConstants.AuditTableName, groupedAuditDatem.Key, auditStorageTableRecords);

            }

            auditTable.RemoveRange(recordsToSync);
            await _dbContext.SaveChangesAsync();
        }

    }
}

My Azure function app startup class我的 Azure function 应用启动 class

using Azure.Identity;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using VPMS.FuncApp.EFCore;
using VPMS.FuncApp.Interfaces;
using VPMS.FuncApp.Services;
using VPMS.Persistence.AuditSetup;
using VPMS.SharedKernel.Interfaces;

[assembly: FunctionsStartup(typeof(VPMS.FuncApp.Startup))]

namespace VPMS.FuncApp;

public sealed class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        var configurations = builder.GetContext().Configuration;

           
        builder.Services.AddAzureClients(builder =>
        {
            builder.AddTableServiceClient(configurations.GetValue<string>("AzureWebJobsStorage"));

            builder.UseCredential(new DefaultAzureCredential());
        });
    }
}

The class the TableStorage inherits from class TableStorage继承自

using Azure;
using Azure.Data.Tables;
using VPMS.Persistence.AuditSetup;

namespace VPMS.FuncApp.EFCore.AuditSetup;

public sealed class AuditTableStorageTable : ITableEntity
{
    public string? UserId { get; set; }
    public AuditType AuditType { get; set; }
    public string TableName { get; set; } = null!;
    public DateTimeOffset CreatedOn { get; set; }
    public string? OldValues { get; set; }
    public string? NewValues { get; set; }
    public string? AffectedColumns { get; set; }
    public string PrimaryKey { get; set; } = null!;
    public Guid BatchId { get; set; }

// these comes from the implemented interface

    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }

    public static AuditTableStorageTable BuilData(Audit audit)
    {
        return new()
        {
            PartitionKey = audit.TableName,
            TableName = audit.TableName,
            AffectedColumns = audit.AffectedColumns,
            AuditType = audit.AuditType,
            BatchId = audit.BatchId,
            CreatedOn = audit.CreatedOn,
            OldValues = audit.OldValues,
            NewValues = audit.NewValues,
            PrimaryKey = audit.PrimaryKey,
            RowKey = Guid.NewGuid().ToString(),
            UserId = audit.UserId,
        };
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 来自 Blazor 服务器应用程序的 Cosmos DB 的 CRUD 操作 - CRUD operations on a Cosmos DB from a Blazor Server App 如何从云 function 对 firestore 数据库进行 CRUD 操作? (节点.js) - How to do CRUD operations on a firestore DB from a cloud function? (Node.js) 超出速率限制:将数据从 pubsub 主题上传到 BQ 时,云 Function 中此表的表更新操作过多 - Exceeded rate limits: too many table update operations for this table in Cloud Function while uploading the data from pubsub topic to BQ 从 azure function 服务的 blob 存储中读取 React 应用程序上的 blob 音频文件 - Read blob audio file on react app from blob storage served by azure function 带有 firebase 连接的 Crud 应用程序(抖动) - Crud app with firebase conncetion (flutter) 从 Google 存储桶触发 R function? - Trigger an R function from Google storage bucket? Zip 从存储帐户部署 azure function - Zip deploy azure function from storage account 将表从 Google BigQuery 导出到 Google Cloud Storage 时出现权限错误 - Permissions Error Exporting a table from Google BigQuery to Google Cloud Storage 将数据从 Cloud Storage 加载到表中的特定分区 - Load data from Cloud Storage to specific partition in table 如何安排从 BigQuery 表到 Cloud Storage 的导出? - How to schedule an export from a BigQuery table to Cloud Storage?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM