Я пишу функцию Azure, которая подписывается на сетку событий и выполняет действия с базой данных SQL Azure при каждом полученном ею событии. В сетке событий публикуются события, когда в одной системе «SecondAppName» возникает ошибка создания, вызванная «Appname» другой системы. По сути, объект создается в одной системе, а аналогичный объект создается в другой (также через публикацию / подписчиков сетки событий). Это приложение-функция ищет сбои в творениях во второй системе, чтобы перезапустить создание. Это еще не все, но я нахожусь в затруднительном положении
Я использую Entity Framework 6 (сначала база данных) для чтения и записи из базы данных. При попытке запросить проект с помощью 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 ...", потому что объект всегда имеет значение NULL.
Я знаю, что это не проблема с подключением, потому что закомментированные строки кода, которые запускают ручной 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-запрос, чтобы заставить это работать, я мог бы даже не использовать Entity Framework.
Вот еще одна важная информация о приложении-функции:
project.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.
Спасибо за любую помощь или совет!
Я нашел проблему. Каким-то образом Entity Framework выполнила первую миграцию кода и добавила другую таблицу под названием «Entity1», из которой он запрашивал вместо этого. Чтобы исправить это, я удалил новую таблицу и добавил аннотацию данных [Table("Entity")]
над моим классом Entity.
В качестве побочного примечания, не связанного с ответом, я настоятельно рекомендую заниматься разработкой функций Azure в Visual Studio и позволять создавать контекст вашей структуры сущностей с помощью инструментов Visual Studio, если вы используете существующую базу данных. Это урок, который я извлек из этой борьбы
Когда вы используете sqlcoffee.com/Azure_0010.htm, какой SQL выполняется вашим нерабочим запросом EF?