Множественные результирующие наборы Entity Framework, устойчивость Azure Connection и перехват команд

Я пытаюсь добавить устойчивость соединения к своему классу репозитория и протестировать его, чтобы переместить мою службу WCF в Azure. У Джули Лерман есть отличный пост:

http://thedatafarm.com/data-access/testing-out-the-connection-resiliency-feature-into-ef6/

Когда я вызываю метод репозитория, который использует обычные запросы Entity Framework, срабатывает метод Interceptor ReaderExecuting, и я могу смоделировать проблему с соединением.

var states = dbContext.Blogs.ToList();

Но по какой-то причине метод Interceptor ReaderExecuting не вызывается, когда выполняется один из моих методов репозитория, который использует "множественные результирующие наборы", возвращенные из хранимой процедуры (см. Код ниже). Я ожидаю, что метод ReaderExecuting вызывается при выполнении "ObjectContext.Translate" или "ToList", но это не так:

db.Database.Connection.Open();

var reader = cmd.ExecuteReader();

var blogs = ((IObjectContextAdapter)db).ObjectContext.Translate<Blog>(reader).ToList();

К вашему сведению, я слежу за этой статьей для обработки "множественных результирующих наборов":

https://msdn.microsoft.com/en-us/data/jj691402.aspx

Я пытаюсь передать стратегию выполнения Entity Framework 6+ для обеспечения устойчивости подключения. Но если он не способен обрабатывать множественные результирующие наборы, моей следующей опцией будет использование библиотеки Polly для обработки временных исключений.

Вы когда-нибудь сталкивались с этой ситуацией?

У вас есть какое-то решение для этого?

3 ответа

Решение

Из-за ограничения EF, упомянутого @tdykstra, я изменил свой хранимый процесс, чтобы он возвращал вывод XML вместо "множественных результирующих наборов". Я использовал метод SqlQuery для вызова хранимой процедуры и получения выходного XML, а затем десериализовал XML в объекты. Таким образом, метод Interceptor ReaderExecuting был выполнен, и я смог проверить устойчивость соединения. Надеемся, что команда EF добавит больше поддержки "множественных наборов результатов" в будущих выпусках. Вот пример кода:

var paramId = new SqlParameter
{
    ParameterName = "id",
    SqlDbType = SqlDbType.Xml,
    Direction = ParameterDirection.Input,
    Value = 1
};

var paramXmlResult = new SqlParameter
{
    ParameterName = "XmlResult",
    SqlDbType = SqlDbType.Xml,
    Direction = ParameterDirection.Output
};

db.Database.SqlQuery<XElement>(
    "EXEC [dbo].[GetDataAsXml] @id, @XmlResult OUT", 
    paramId, paramXmlResult).ToList();


XElement xmlResult = XElement.Parse(paramXmlResult.Value.ToString());

//FromXElement is an Extension method that deserializes XML into a Type (like MyData)
MyData data = xmlResult.FromXElement<MyData>();

В этом сценарии вызов ExecuteReader выходит за рамки EF - код вызывает его непосредственно в объекте команды ADO.NET. Поскольку вы полностью обходите EF для выполнения команды, вы пропускаете все EF (включая перехватчики). Translate просто берет уже полученные результаты и заполняет их в объекты.

Вы пробовали подключить встроенную отказоустойчивость соединения из пользовательских DbConfiguration реализация как так?

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration()
        : base()
    {
        var strategy = System.Data.Entity.SqlServer.SqlAzureExecutionStrategy();
        SetExecutionStrategy("System.Data.EntityClient", strategy);
        SetExecutionStrategy("System.Data.SqlClient", strategy);
    }
}

Я использовал этот подход с MARS, и у меня не было проблем с ним.

Другие вопросы по тегам