-1

我正在编写一个订阅事件网格的 Azure 函数,并针对它接收到的每个事件对 Azure SQL 数据库执行操作。当一个系统“SecondAppName”中发生由另一个系统“Appname”触发的创建错误时,事件网格会向其发布事件。基本上,在一个系统中创建一个实体,然后在另一个系统中创建一个类似实体(也通过事件网格发布/订阅者)。此函数应用在第二个系统中查找创建失败,以便重新触发创建。这还没有完成,但我遇到了障碍

我正在使用 Entity Framework 6 (Database First) 从数据库中读取和写入。尝试使用 Entity Framework 查询项目FindAsync()时,结果将返回为 null。以下是我的组织名称的相关代码:

#r "Newtonsoft.Json"
#r "System.Configuration"
#r "System.Data"
#r "System.Data.Common"

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Configuration;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.SqlServer;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

public static async Task Run(JObject eventGridEvent, TraceWriter log)
{
    log.Info($"event was: {eventGridEvent.ToString(Formatting.Indented)}");
    var eventGridEventProperties = eventGridEvent.Properties().ToList();
    if(
        eventGridEventProperties.Count(
            prop => prop.Name == "eventType" && prop.Value.ToString() == "error"
        ) > 0 &&
        eventGridEventProperties.Count(
            prop => prop.Name == "subject" && prop.Value.ToString() == "/appname/subject1"
        ) > 0
    )
    {
        var appnameSecondAppNameErrorEvent = eventGridEvent.ToObject<AppnameSecondAppNameErrorEvent>();
        var entityId = appnameSecondAppNameErrorEvent.Data.EntityId;
        log.Info($"subject1 create event error found for UAT Entity {entityId}");
        log.Info($"trying to query entity data for UAT Entity {entityId}");

        try
        {
            string connectionString = ConfigurationManager.ConnectionStrings["AppnameContext"].ToString();
            using (var _appnameContext = new AppnameDbContext(connectionString))
            {
                var entity = await _appnameContext.Entity.FindAsync(entityId)
                // var enitty = await _appnameContext
                //     .Entity
                //     .SqlQuery("select * from Entity where EntityId=@id", new SqlParameter("@id", entityId))
                //     .FirstOrDefaultAsync();

                if(entity != null)
                {
                    log.Info(
                        $@"Entity was Id: {entity.EntityId}, 
                           Name: {entity.Name}, 
                           Property1: {entity.Property1Name}, 
                           Property2Name: {entity.Property2Name}"
                    );
                }
                else
                {
                    throw new Exception($"UAT Entity {entityId} not found");
                }

            }
        }
        catch (Exception ex)
        {
            log.Info($"Error getting Appname UAT Entity {entityId} with reason: {ex.Message}");
        }
    }
}

public class AppnameSecondAppNameErrorEvent
{
    public Guid Id { get; set; }
    public string Subject { get; set; }
    public string EventType { get; set; }
    public DateTime EventTime { get; set; }
    public AppnameSecondAppNameErrorEventData Data { get; set; }
    public string DataVersion { get; set; }
    public string MetaDataVersion { get; set; }
    public string Topic { get; set; }
}

public class AppnameSecondAppNameErrorEventData
{
    public Guid EntityId { get; set; }
    public string ErrorMessage { get; set; }
}

public class AppnameDbContext : DbContext
{
    public AppnameDbContext(string cs) : base(cs) { }
    public DbSet<Entity> Entity { get;set; }
}

public class Entity
{
    [Key]
    public Guid EntityId { get; set; }
    public string Name { get; set; }
    public string Property1Name { get; set; }
    public string Property2Name { get; set; }
}

它总是抛出异常“UAT Entity Not Found ...”,因为实体始终为空

我知道这不是连接问题,因为注释掉的运行手动 SQL 查询的代码行会返回结果。这也意味着结果也存在于数据库中。此外,如果我运行这样的行:

 var entity = await _appnameContext
                        .Entity
                        .SqlQuery("select * from Entity where EntityId=@id", new SqlParameter("@id", entityId))
                        .FirstOrDefaultAsync();
var entity2 = await _appnameContext.Entity.FindAsync(entityId);

entity2有结果,所以它附加到上下文中。

我在这里做错了什么?如果我必须手动运行 SQL 查询才能让它工作,我什至可能不使用实体框架

以下是有关函数应用的更多相关信息:

项目.json:

{
    "frameworks": {
        "net46":{
            "dependencies": {
                "EntityFramework": "6.1.2",
                "System.Data.Common": "4.3.0"
            }
        }
    }
}

函数应用设置中的连接字符串(组织详细信息和凭据被隐藏):

Server=tcp:server.database.windows.net,1433;Initial Catalog=DATABASE;Persist Security Info=False;User ID=username;Password=password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

该数据库的用户是管理员。

下面是一个显示事件的示例:

{
    "id": "621ed36b-13df-4af3-af45-3cff2434cea7",
    "subject": "/appname/subject1",
    "eventType": "error",
    "eventTime": "2018-08-14T17:30:59.4395766Z",
    "data": {
        "entityId": "67d14894-1a0c-4c6d-b091-544260d89642",
        "errorMessage": "Error creating the entity"
    },
    "dataVersion": "",
    "metadataVersion": "1",
    "topic": "/subscriptions/..."
}

最后值得注意的是,我没有使用 Visual Studio 进行编程,而是使用 Azure 门户的 Web 界面来执行此操作。

感谢您的任何帮助或建议!

4

1 回答 1

0

我发现了这个问题。不知何故,Entity Framework 执行了代码优先迁移,并添加了另一个名为“Entity1”的表,它正在查询该表。[Table("Entity")]为了解决这个问题,我删除了新表,并在我的实体类上方添加了数据注释

于 2018-08-17T19:58:00.890 回答