实体框架多个结果集,Azure连接弹性和命令拦截

时间:2015-08-10 21:27:10

标签: c# entity-framework wcf azure resiliency

我正在尝试将Connection Resiliency添加到我的Repository类并对其进行测试,以便将我的WCF服务移动到Azure。 Julie Lerman有一篇很棒的文章:

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

当我调用使用正常实体框架查询的存储库方法时,Interceptor ReaderExecuting方法被触发,我能够模拟连接问题。

var states = dbContext.Blogs.ToList();

但由于某种原因,当我正在执行一个使用从存储过程返回的“多个结果集”的存储库方法时,不会调用Interceptor ReaderExecuting方法(请参阅下面的代码)。我希望在" ObjectContext.Translate"时调用ReaderExecuting方法。或" 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

我正在努力转发实体框架6+执行策略以处理连接弹性。但如果它不能处理多个结果集,我的下一个选项将使用Polly库进行瞬态异常处理。

你遇到过这种情况吗?

你有解决方法吗?

3 个答案:

答案 0 :(得分:0)

您是否尝试过这样的自定义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一起使用,而且我没有遇到任何问题。

答案 1 :(得分:0)

在这种情况下,对ExecuteReader的调用超出了EF的范围 - 代码直接在ADO.NET命令对象上调用它。因为你完全绕过EF来执行命令,所以你错过了所有EF(包括拦截器)。翻译只需获取已检索的结果并将其填充到对象中。

答案 2 :(得分:0)

由于@tdykstra提到的EF限制,我更改了我的stored-proc以返回XML输出而不是&#34;多个结果集&#34;。我使用了&#34; SqlQuery&#34;调用stored-proc并获取输出XML的方法,然后我将XML反序列化为对象。这样Interceptor ReaderExecuting方法得到了执行,我能够测试连接弹性。希望EF团队为&#34;多个结果集添加更多支持&#34;在未来的版本。 以下是示例代码:

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>();