EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

本章原文地址:Connection Resiliency and Command Interception

原文有些地方讲的比较细,个人根据实际理解做些缩减,或者加入一些个人理解;

第1部分 弹性连接

为什么要弹性连接?什么是弹性连接?

在实际的网络应用中,尤其是在Internet上的网络应用,就算Web服务器和数据库服务器在一个数据中心,也不能保证WEB服务器和数据库服务器没有任何延迟或者其他网络问题;

尤其如PaaS层的Azure的SQL或者阿里的SQL、MySQL数据库服务器,都是做了网络负载均衡的,在一定的条件下能提供的服务是有限的,在其SLA里都会有定义;

而超出其SLA的部分请求就会被取消响应,那么在WEB网页应用设计的时候,就需要考虑这一点,在出现一些异常情况的时候,需要能够在短时间内进行一次或多次Retry.

这就称为:弹性的连接

原文中对EF6实现弹性连接功能仅做了简单代码就实现了,至于具体在实际项目中是不是就这么简单,本人还需要进一步深入学习。

先看看原文如何做的:

在DAL文件夹定义 SchoolConfiguration类,继承自DbConfiguration类, 在这个类中设置SQL数据库的执行策略 (execution strategy ,这个名词是EF6 对于Retry Policy 的命名

using System.Data.Entity;
using System.Data.Entity.SqlServer; namespace EFTest.DAL
{
public class SchoolConfiguration : DbConfiguration
{
public SchoolConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
}
}
}

EF6会自动运行继承自DbConfiguration类的代码;当然也可以通过配置Web.config 来实现,可以参考 EntityFramework Code-Based Configuration
然后在 Student 控制器里增加申明:

using System.Data.Entity.Infrastructure;

最后就是将所有 Try-catch代码块的 catch 后面捕获的 Exception 类型转为 RetryLimitExceededException

catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}

这样就会是出现数据库连接异常的时候,进行Retry,多次Retry达到Limit值还是错误,则抛出异常。

更多的说明,需要参考: Entity Framework Connection Resiliency / Retry Logic

第2部分 命令拦截调试

设置好了弹性连接后,如何能够看到到底是不是Retry了,则需要一些调试手段;

当然你可以使用Web请求Log等来查看,或者EF6 提供的Dedicated Logging API (dedicated logging API)

本次直接采用EF6的 Interception 功能来实现。

对于日志记录来说,最好的方式是做一个接口来定义,而不是直接每次用硬代码来Call System.Diagnostics.Trace

因为这样,对于以后如果日志记录机制有调整的话,就容易很多了。

实际操作体验:

1、新建一个Logging 的文件夹

2、在文件夹中新建一个ILogger 接口,接口中定义了不同等级的信息处理方式;

TraceApi 可以跟踪连接外部服务例如SQL服务的每一步延迟情况;

using System;

namespace EFTest.Logging
{
public interface ILogger
{
void Information(string message);
void Information(string fmt, params object[] vars);
void Information(Exception exception, string fmt, params object[] vars); void Warning(string message);
void Warning(string fmt, params object[] vars);
void Warning(Exception exception, string fmt, params object[] vars); void Error(string message);
void Error(string fmt, params object[] vars);
void Error(Exception exception, string fmt, params object[] vars); void TraceApi(string componentName, string method, TimeSpan timespan);
void TraceApi(string componentName, string method, TimeSpan timespan, string properties);
void TraceApi(string componentName, string method, TimeSpan timespan, string fmt, params object[] vars);
}
}

3、在文件夹内新建Logger这个类,集成自ILogger接口,并实现接口内方法;

using System;
using System.Diagnostics;
using System.Text; namespace EFTest.Logging
{
public class Logger : ILogger
{
public void Information(string message)
{
Trace.TraceInformation(message);
} public void Information(string fmt, params object[] vars)
{
Trace.TraceInformation(fmt, vars);
} public void Information(Exception exception, string fmt, params object[] vars)
{
Trace.TraceInformation(FormatExceptionMessage(exception, fmt, vars));
} public void Warning(string message)
{
Trace.TraceWarning(message);
} public void Warning(string fmt, params object[] vars)
{
Trace.TraceWarning(fmt, vars);
} public void Warning(Exception exception, string fmt, params object[] vars)
{
Trace.TraceWarning(FormatExceptionMessage(exception, fmt, vars));
} public void Error(string message)
{
Trace.TraceError(message);
} public void Error(string fmt, params object[] vars)
{
Trace.TraceError(fmt, vars);
} public void Error(Exception exception, string fmt, params object[] vars)
{
Trace.TraceError(FormatExceptionMessage(exception, fmt, vars));
} public void TraceApi(string componentName, string method, TimeSpan timespan)
{
TraceApi(componentName, method, timespan, "");
} public void TraceApi(string componentName, string method, TimeSpan timespan, string fmt, params object[] vars)
{
TraceApi(componentName, method, timespan, string.Format(fmt, vars));
}
public void TraceApi(string componentName, string method, TimeSpan timespan, string properties)
{
string message = String.Concat("Component:", componentName, ";Method:", method, ";Timespan:", timespan.ToString(), ";Properties:", properties);
Trace.TraceInformation(message);
} private static string FormatExceptionMessage(Exception exception, string fmt, object[] vars)
{
// Simple exception formatting: for a more comprehensive version see
// http://code.msdn.microsoft.com/windowsazure/Fix-It-app-for-Building-cdd80df4
var sb = new StringBuilder();
sb.Append(string.Format(fmt, vars));
sb.Append(" Exception: ");
sb.Append(exception.ToString());
return sb.ToString();
}
}
}

看代码可以知道,实际是通过.NET 的 System.Diagnostics 来跟踪记录日志的;日志信息可以写到很多其他位置,例如Azure 的blob storage ;

本次,只是把日志输出到VS 的Output窗口;

在实际项目中,如果用其他记录日志机制来代替 System.Diagnostics的话,ILogging接口方式比较容易来实现这个切换。

下一步需要建一个拦截类来进行对EF6每一次向数据库发SQL请求的时候进行拦截记录日志或者发一个模拟的短暂错误;

这个类必须继承自 DbCommandInterceptor

在DAL文件夹新建 SchoolInterceptorLogging类,集成自DbCommandInterceptor

using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure.Interception;
using System.Data.Entity.SqlServer;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Reflection;
using System.Linq;
using EFTest.Logging; namespace EFTest.DAL
{
public class SchoolInterceptorLogging : DbCommandInterceptor
{
private ILogger _logger = new Logger();
private readonly Stopwatch _stopwatch = new Stopwatch(); public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
base.ScalarExecuting(command, interceptionContext);
_stopwatch.Restart();
} public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_stopwatch.Stop();
if (interceptionContext.Exception != null)
{
_logger.Error(interceptionContext.Exception, "Error executing command: {0}", command.CommandText);
}
else
{
_logger.TraceApi("SQL Database", "SchoolInterceptor.ScalarExecuted", _stopwatch.Elapsed, "Command: {0}: ", command.CommandText);
}
base.ScalarExecuted(command, interceptionContext);
} public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
base.NonQueryExecuting(command, interceptionContext);
_stopwatch.Restart();
} public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_stopwatch.Stop();
if (interceptionContext.Exception != null)
{
_logger.Error(interceptionContext.Exception, "Error executing command: {0}", command.CommandText);
}
else
{
_logger.TraceApi("SQL Database", "SchoolInterceptor.NonQueryExecuted", _stopwatch.Elapsed, "Command: {0}: ", command.CommandText);
}
base.NonQueryExecuted(command, interceptionContext);
} public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
base.ReaderExecuting(command, interceptionContext);
_stopwatch.Restart();
}
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_stopwatch.Stop();
if (interceptionContext.Exception != null)
{
_logger.Error(interceptionContext.Exception, "Error executing command: {0}", command.CommandText);
}
else
{
_logger.TraceApi("SQL Database", "SchoolInterceptor.ReaderExecuted", _stopwatch.Elapsed, "Command: {0}: ", command.CommandText);
}
base.ReaderExecuted(command, interceptionContext);
}
}
}

另外,为了模拟在筛选查询的时候产生一个短暂错误,写一个类让用户在输入框内输入 Throw 的触发这个错误,在DAL文件夹里建SchoolInterceptorTransientErrors类:

重载了ReaderExecuting方法,当用户输入的是Throw的时候,做一个特殊处理来进行测试;

如果希望测试其他数据库操作,则可以考虑重载 NonQueryExecutingScalarExecuting这两个方法。

using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using System.Data.SqlClient;
using System.Reflection;
using System.Linq;
using EFTest.Logging; namespace EFTest.DAL
{
public class SchoolInterceptorTransientErrors : DbCommandInterceptor
{
private int _counter = ;
private ILogger _logger = new Logger(); public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
bool throwTransientErrors = false;
if (command.Parameters.Count > && command.Parameters[].Value.ToString() == "%Throw%")
{
throwTransientErrors = true;
command.Parameters[].Value = "%an%";
command.Parameters[].Value = "%an%";
} if (throwTransientErrors && _counter < )
{
_logger.Information("Returning transient error for command: {0}", command.CommandText);
_counter++;
interceptionContext.Exception = CreateDummySqlException();
}
} private SqlException CreateDummySqlException()
{
// The instance of SQL Server you attempted to connect to does not support encryption
var sqlErrorNumber = ; var sqlErrorCtor = typeof(SqlError).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).Where(c => c.GetParameters().Count() == ).Single();
var sqlError = sqlErrorCtor.Invoke(new object[] { sqlErrorNumber, (byte), (byte), "", "", "", }); var errorCollection = Activator.CreateInstance(typeof(SqlErrorCollection), true);
var addMethod = typeof(SqlErrorCollection).GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic);
addMethod.Invoke(errorCollection, new[] { sqlError }); var sqlExceptionCtor = typeof(SqlException).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).Where(c => c.GetParameters().Count() == ).Single();
var sqlException = (SqlException)sqlExceptionCtor.Invoke(new object[] { "Dummy", errorCollection, null, Guid.NewGuid() }); return sqlException;
}
}
}

在Global.asax中添加声明:
using System.Data.Entity.Infrastructure.Interception;

并在Application_Start()方法中增加后面两行代码:

        protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
//Database.SetInitializer<SchoolContext>(new SchoolInitializer());
DbInterception.Add(new SchoolInterceptorTransientErrors());
DbInterception.Add(new SchoolInterceptorLogging());
}

当然,这两行代码可以加在SchoolConfiguration类里,初始化的时候直接加载执行:(注:上面和下面两段代码只能选其中一种

using System.Data.Entity;
using System.Data.Entity.Infrastructure.Interception;
using System.Data.Entity.SqlServer; namespace EFTest.DAL
{
public class SchoolConfiguration : DbConfiguration
{
public SchoolConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
DbInterception.Add(new SchoolInterceptorTransientErrors());
DbInterception.Add(new SchoolInterceptorLogging());
}
}
}

下面就可以进行测试了,进Home/Index后点Students,进入Student/Index 就会发现VS 的Output 窗口有一些Debug信息输出:

SELECT Count(*)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE t.TABLE_SCHEMA + '.' + t.TABLE_NAME IN ('dbo.Course','dbo.Enrollment','dbo.Student')
OR t.TABLE_NAME = 'EdmMetadata':
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:04:11.0689220Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"yqYB5YWz4YY=","ai.operation.id":"yqYB5YWz4YY="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | master","id":"+xoBYBiNrPM=","value":0.3565,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ScalarExecuted;Timespan:::00.0233412;Properties:Command: IF db_id(N'EFTest') IS NOT NULL SELECT ELSE SELECT Count(*) FROM sys.databases WHERE [name]=N'EFTest':
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:04:11.2577658Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"yqYB5YWz4YY=","ai.operation.id":"yqYB5YWz4YY="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"hGEE5js+frc=","value":1.2592,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0260725;Properties:Command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
WHERE [Extent1].[ContextKey] = @p__linq__0
) AS [GroupBy1]:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:04:11.3081972Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"yqYB5YWz4YY=","ai.operation.id":"yqYB5YWz4YY="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"ULROylXtnGQ=","value":1.6166,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0155956;Properties:Command: SELECT TOP ()
[Project1].[C1] AS [C1],
[Project1].[MigrationId] AS [MigrationId],
[Project1].[Model] AS [Model],
[Project1].[ProductVersion] AS [ProductVersion]
FROM ( SELECT
[Extent1].[MigrationId] AS [MigrationId],
[Extent1].[Model] AS [Model],
[Extent1].[ProductVersion] AS [ProductVersion],
AS [C1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
WHERE [Extent1].[ContextKey] = @p__linq__0
) AS [Project1]
ORDER BY [Project1].[MigrationId] DESC:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:04:11.3703060Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"yqYB5YWz4YY=","ai.operation.id":"yqYB5YWz4YY="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"/xZUhdnSdM8=","value":1.7563,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0176946;Properties:Command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
) AS [GroupBy1]:
'iisexpress.exe' (CLR v4.0.30319: /LM/W3SVC//ROOT--): Loaded 'EntityFrameworkDynamicProxies-EFTest'.
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:04:11.4280626Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"yqYB5YWz4YY=","ai.operation.id":"yqYB5YWz4YY="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"bDKxb2FBJ1g=","value":0.9676,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0194244;Properties:Command: SELECT
[Extent1].[ID] AS [ID],
[Extent1].[LastName] AS [LastName],
[Extent1].[FirstMidName] AS [FirstMidName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate]
FROM [dbo].[Student] AS [Extent1]
ORDER BY [Extent1].[LastName] ASC
OFFSET ROWS FETCH NEXT ROWS ONLY :
'iisexpress.exe' (CLR v4.0.30319: /LM/W3SVC//ROOT--): Loaded 'C:\Users\jaczhang\AppData\Local\Temp\Temporary ASP.NET Files\root\644be5f6\480b064f\App_Web_jlggwjiw.dll'.
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Request","time":"2017-08-25T07:04:10.5173746Z","tags":{"ai.operation.id":"yqYB5YWz4YY=","ai.internal.sdkVersion":"web: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index"},"data":{"baseType":"RequestData","baseData":{"ver":,"id":"yqYB5YWz4YY=","name":"GET Student/Index","startTime":"2017-08-25T15:04:10.5173746+08:00","duration":"00:00:01.6326287","success":true,"responseCode":"","url":"http://localhost:9910/Student","httpMethod":"GET","properties":{"DeveloperMode":"true"}}}}

然后在筛选输入框输入Throw 点确定: 可以看到里面触发一个 代码为20的短暂错误:

iisexpress.exe Information:  : Returning transient error for command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1]
iisexpress.exe Error: : Error executing command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1] Exception: System.Data.SqlClient.SqlException (0x80131904): Dummy
ClientConnectionId:9b424f7d-306b-450b-8a3e-58198487b8bb
Error Number:,State:,Class:
iisexpress.exe Information: : Returning transient error for command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1]
iisexpress.exe Error: : Error executing command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1] Exception: System.Data.SqlClient.SqlException (0x80131904): Dummy
ClientConnectionId:941ac661-66d3--a690-188d13144150
Error Number:,State:,Class:
iisexpress.exe Information: : Returning transient error for command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1]
iisexpress.exe Error: : Error executing command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1] Exception: System.Data.SqlClient.SqlException (0x80131904): Dummy
ClientConnectionId:47685ec4-e837-4e05-bbb3-948e3f3f87a8
Error Number:,State:,Class:
iisexpress.exe Information: : Returning transient error for command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1]
iisexpress.exe Error: : Error executing command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1] Exception: System.Data.SqlClient.SqlException (0x80131904): Dummy
ClientConnectionId:35de62b7-cda6-4db7-88e0-48d708f42826
Error Number:,State:,Class:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:06:51.9163289Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"kZm9/0YA8y4=","ai.operation.id":"kZm9/0YA8y4="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"0iOb6Vj5zqI=","value":3.3859,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0382038;Properties:Command: SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [GroupBy1]:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-08-25T07:06:51.9705260Z","tags":{"ai.internal.sdkVersion":"rddf: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index","ai.operation.parentId":"kZm9/0YA8y4=","ai.operation.id":"kZm9/0YA8y4="},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":,"name":"(localdb)\\ProjectsV13 | EFTest","id":"b1S5ExJ8ugQ=","value":2.5604,"dependencyKind":,"success":true,"properties":{"DeveloperMode":"true"}}}}
iisexpress.exe Information: : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:::00.0195543;Properties:Command: SELECT
[Project1].[ID] AS [ID],
[Project1].[LastName] AS [LastName],
[Project1].[FirstMidName] AS [FirstMidName],
[Project1].[EnrollmentDate] AS [EnrollmentDate]
FROM ( SELECT
[Extent1].[ID] AS [ID],
[Extent1].[LastName] AS [LastName],
[Extent1].[FirstMidName] AS [FirstMidName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[LastName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[FirstMidName] LIKE @p__linq__1 ESCAPE N'~')
) AS [Project1]
ORDER BY [Project1].[LastName] ASC
OFFSET ROWS FETCH NEXT ROWS ONLY :
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Request","time":"2017-08-25T07:06:40.0512275Z","tags":{"ai.operation.id":"kZm9/0YA8y4=","ai.internal.sdkVersion":"web: 2.0.0.25000","ai.device.roleInstance":"chnsbopc02.dc01.fujixerox.net","ai.operation.name":"GET Student/Index"},"data":{"baseType":"RequestData","baseData":{"ver":,"id":"kZm9/0YA8y4=","name":"GET Student/Index","startTime":"2017-08-25T15:06:40.0512275+08:00","duration":"00:00:11.9404844","success":true,"responseCode":"","url":"http://localhost:9910/Student?SearchString=Throw","httpMethod":"GET","properties":{"DeveloperMode":"true"}}}}

为了看Retry是否其作用,可以先注释掉以下行:
  public SchoolConfiguration()
        {
            //SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());           
        }

然后再进入网页,输入Throw后点确定,就会发现出现了数据库错误:

看起来是起作用了;

最后记得把刚才注释掉的行取消注释。

EF6学习笔记(四) 弹性连接及命令拦截调试的更多相关文章

  1. 【EF6学习笔记】(四)弹性连接及命令拦截调试

    本章原文地址:Connection Resiliency and Command Interception 原文有些地方讲的比较细,个人根据实际理解做些缩减,或者加入一些个人理解: 第1部分 弹性连接 ...

  2. [翻译][MVC 5 + EF 6] 4:弹性连接和命令拦截

    原文:Connection Resiliency and Command Interception with the Entity Framework in an ASP.NET MVC Applic ...

  3. Monkey学习笔记<四>:Monkey服务器命令

    #使用如下命令将本地pc和手机连接起来 adb shell monkey --port 1080 adb forward tcp 1080:tcp 1080 telnet localhost 1080 ...

  4. 【linux学习笔记四】文件搜索命令

    一 文件搜索 locate //在后台数据库中按文件名搜索 搜索速度更快 locate 文件名 //locate命令所搜索的后台数据库 /var/lib/mlocate //更新数据库 updated ...

  5. 【EF6学习笔记】目录

    [EF6学习笔记](一)Code First 方式生成数据库及初始化数据库实际操作 [EF6学习笔记](二)操练 CRUD 增删改查 [EF6学习笔记](三)排序.过滤查询及分页 [EF6学习笔记]( ...

  6. ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

    个人从传统的CS应用开发(WPF)开始转向BS架构应用开发: 先是采用了最容易上手也是最容易搞不清楚状况的WebForm方式入手:到后面就直接抛弃了服务器控件的开发方式,转而采用 普通页面+Ajax+ ...

  7. openresty 学习笔记四:连接mysql和进行相关操作

    openresty 学习笔记四:连接mysql和进行相关操作 毕竟redis是作为缓存,供程序的快速读写,虽然reidis也可以做持久化保存,但还是需要一个做数据存储的数据库.比如首次查询数据在red ...

  8. EF6学习笔记(六) 创建复杂的数据模型

    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇原文地址:Creating a More Complex Data Model 本篇讲的比较碎,很多内容本人 ...

  9. EF6 学习笔记(五):数据库迁移及部署

    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...

随机推荐

  1. django之两个使用模板的例子

    from django.db import models # Create your models here. class Book(models.Model): title=models.CharF ...

  2. Android 开发 框架系列 glide-transformations 图片处理基本使用

    首先简单的介绍一下Gilde作用范围.Gilde功能十分强大,它可以实现图片处理.图片本地加载.图片网络加载.位图加载.图片内存缓存.图片磁盘缓存.Gif图片加载.使用简单轻松,轻松的后是它强大的心, ...

  3. python——vs2017安装python库时,提示pip指令问题。

    需要跟新pip指令 方法: 第一步:打开vs2017 后新建一个python 文件 后面如图 点击红色部分 2.在框中输入pip之后更新即可 如图 3.问题解决 倘若还有问题 欢迎分享

  4. 0初识Linux

    今天三八妇女节,Linux就该这么学,开课第一天.信心满满,激动,期待,要努力了.(博客为预习写的,今天又做了更新.)   Linux第一印象就是黑色背景屏幕,上面还有好多代码,敲的一手好的命令操控着 ...

  5. linux使用privoxy将55转为http代理

    =============================================== 2018/3/21_第3次修改                       ccb_warlock 更新 ...

  6. springboot中配置文件application.properties的配置详情,数据源配置

    pring Boot使用了一个全局的配置文件application.properties,放在src/main/resources目录下或者类路径的/config下.Sping Boot的全局配置文件 ...

  7. Linux网络编程学习(三) ----- 进程控制实例(第三章)

    本节主要介绍一个进程控制的实例,功能就是在前台或者后台接收命令并执行命令,还能处理由若干个命令组成的命令行,该程序命名为samllsh. 基本逻辑就是 while(EOF not typed) { 从 ...

  8. 虚拟网络VDC与VPC

    当前互联网行业,内部 IT 基础资源云端化是主要趋势.云平台将资源管理抽象出来,比如云主机.云 DB 等,以服务的方式提供给用户,按需使用,从而带来更大的灵活性与经济性. 随着主机.DB.缓存.存储等 ...

  9. Python类继承(转发)

    目录 一.概述 二.类的继承 2.1 继承的定义 2.2 构造函数的继承 2.3 子类对父类方法的重写 三.类继承的事例 回到顶部 一.概述 面向对象编程 (OOP) 语言的一个主要功能就是“继承”. ...

  10. python import hashllb

    http://www.cnblogs.com/alex3714/articles/5161349.html 用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224 ...