diff --git a/README.md b/README.md
index 66c037bc..01c7d389 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ Following API reference documentation provides guidance for using the SDK and mo
4. [Trace AWS SDK request](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-aws-sdk-request-net-and-net-core--nuget)
5. [Trace out-going HTTP requests](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-out-going-http-requests-net-and-net-core--nuget)
6. [Trace Query to SQL Server](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-query-to-sql-server-net-and-net-core--nuget)
-7. [Trace SQL Query through Entity Framework Core 3.0 and above](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-core-30-and-above-net-core--nuget)
+7. [Trace SQL Query through Entity Framework](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-net-and-net-core--nuget)
8. [Multithreaded Execution](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#multithreaded-execution-net-and-net-core--nuget)
9. [Trace custom methods ](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-custom-methods-net-and-net-core)
10. [Creating custom Segment/Subsegment](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#creating-custom-segmentsubsegment-net-and-net-core)
@@ -384,7 +384,11 @@ using (var command = new TraceableSqlCommand("SELECT * FROM products", connectio
2. Parameterized values will appear in their tokenized form and will not be expanded.
3. The value of `collectSqlQueries` in the `TraceableSqlCommand` instance overrides the value set in the global configuration using the `CollectSqlQueries` property.
-### Trace SQL Query through Entity Framework Core 3.0 and above (.NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/)
+### Trace SQL Query through Entity Framework (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/)
+
+#### Setup
+
+##### .NET Core
AWS XRay SDK for .NET Core provides interceptor for tracing SQL query through Entity Framework Core (>=3.0).
@@ -397,8 +401,6 @@ For how to start with Entity Framework Core in an ASP.NET Core web app, please t
*Known Limitation (as of 12-03-2020):* If you're using another `DbCommandInterceptor` implementation along with the `AddXRayInterceptor` in the `DbContext`, it may not work as expected and you may see a "EntityNotAvailableException" from the XRay EFCore interceptor. This is due to [`AsyncLocal`](https://docs.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=netcore-2.0) not being able to maintain context across the `ReaderExecutingAsync` and `ReaderExecutedAsync` methods. Ref [here](https://github.com/dotnet/efcore/issues/22766) for more details on the issue.
-#### Setup
-
In order to trace SQL query, you can register your `DbContext` with `AddXRayInterceptor()` accordingly in the `ConfigureServices` method in `startup.cs` file.
For instance, when dealing with MySql server using Nuget: [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql) (V 3.1.1).
@@ -426,10 +428,45 @@ public class your_DbContext : DbContext
The connection string can be either hard coded or configured from `appsettings.json` file.
+##### .NET
+
+AWS XRay SDK for .NET provides interceptor for tracing SQL query through Entity Framework 6 (>= 6.2.0).
+
+For how to start with Entity Framework 6 in an ASP.NET web app, please take reference to [link](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application).
+
+For instrumentation, you will need to install `AWSXRayRecorder.Handlers.EntityFramework` nuget package and call `AWSXRayEntityFramework6.AddXRayInterceptor()` in your code. Make sure to call it **only once** to avoid duplicate tracing.
+
+For instance, you can call `AddXRayInterceptor()` in the `Application_Start` method of **Global.asax** file.
+
+```
+using Amazon.XRay.Recorder.Handlers.EntityFramework;
+
+protected void Application_Start()
+{
+ AWSXRayEntityFramework6.AddXRayInterceptor();
+}
+```
+
+Or you can call it in the `DbConfiguration` class if there is one in your application to configure execution policy.
+
+```
+using Amazon.XRay.Recorder.Handlers.EntityFramework;
+
+public class YourDbConfiguration : DbConfiguration
+{
+ public YourDbConfiguration()
+ {
+ AWSXRayEntityFramework6.AddXRayInterceptor();
+ }
+}
+```
+
#### Capture SQL Query text in the traced SQL calls to SQL Server
You can also opt in to capture the `DbCommand.CommandText` as part of the subsegment created for your SQL query. The collected `DbCommand.CommandText` will appear as `sanitized_query` in the subsegment JSON. By default, this feature is disabled due to security reasons.
+##### .NET Core
+
If you want to enable this feature, it can be done in two ways. First, by setting the `CollectSqlQueries` to **true** in the `appsettings.json` file as follows:
```json
@@ -440,7 +477,7 @@ If you want to enable this feature, it can be done in two ways. First, by settin
}
```
-Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`.
+Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `appsettings.json` mentioned above.
```csharp
using Microsoft.EntityFrameworkCore;
@@ -463,6 +500,26 @@ public class your_DbContext : DbContext
}
```
+##### .NET
+
+You can enable tracing SQL query text for EF 6 interceptor in the `Web.config` file.
+
+```xml
+
+
+
+
+
+```
+
+You can also pass **true** to `AddXRayInterceptor()` to collect SQL query text, otherwise pass **false** to disable. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `Web.config` mentioned above.
+
+```
+using Amazon.XRay.Recorder.Handlers.EntityFramework;
+
+AWSXRayEntityFramework6.AddXRayInterceptor(true);
+```
+
### Multithreaded Execution (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Core/)
In multithreaded execution, X-Ray context from current to its child thread is automatically set.
diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs b/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs
new file mode 100644
index 00000000..c17fb06c
--- /dev/null
+++ b/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License").
+// You may not use this file except in compliance with the License.
+// A copy of the License is located at
+//
+// http://aws.amazon.com/apache2.0
+//
+// or in the "license" file accompanying this file. This file is distributed
+// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the License for the specific language governing
+// permissions and limitations under the License.
+//
+//-----------------------------------------------------------------------------
+
+using System.Data.Entity.Infrastructure.Interception;
+
+namespace Amazon.XRay.Recorder.Handlers.EntityFramework
+{
+ ///
+ /// Class for to add .
+ /// User can pass collectSqlQueries to AddXRayInterceptor() to decide if sanitized_query should be included in the trace
+ /// context or not.
+ ///
+ public static class AWSXRayEntityFramework6
+ {
+ ///
+ /// Enable tracing SQL queries through EntityFramework 6 for .NET framework by calling AWSXRayEntityFramework6.AddXRayInterceptor() to add into to register X-Ray tracing interceptor.
+ ///
+ /// Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in Web.config if present. The default value of this parameter is null.
+ public static void AddXRayInterceptor(bool? collectSqlQueries = null)
+ {
+ DbInterception.Add(new EFInterceptor(collectSqlQueries));
+ }
+ }
+}
diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs b/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs
index 83084c45..c9919ea9 100644
--- a/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs
+++ b/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs
@@ -30,7 +30,7 @@ public static class AWSXRayInterceptorExtensions
/// Add to .
///
/// Instance of .
- ///
+ /// Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in appsettings.json if present. The default value of this parameter is null.
/// Instance of .
public static DbContextOptionsBuilder AddXRayInterceptor(this DbContextOptionsBuilder dbContextOptionsBuilder, bool? collectSqlQueries = null)
{
diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj
index baaa9804..14865753 100644
--- a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj
+++ b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj
@@ -1,7 +1,7 @@
- netstandard2.0
+ net45;netstandard2.0Amazon.com, IncAmazon Web Service X-Ray RecorderCopyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -11,7 +11,7 @@
AWSXRayRecorder.Handlers.EntityFrameworkAmazon.XRay.Recorder.Handlers.EntityFrameworkAmazon Web Services
- This package contains libraries to trace SQL queries through Entity Framework Core.
+ This package contains libraries to trace SQL queries through Entity Framework.http://aws.amazon.com/apache2.0/https://aws.amazon.com/documentation/xray/https://github.com/aws/aws-xray-sdk-dotnet
@@ -30,8 +30,16 @@
1701;1702;1591;
-
+
+
+
+
+
+
+
+
+
diff --git a/sdk/src/Handlers/EntityFramework/EFInterceptor.cs b/sdk/src/Handlers/EntityFramework/EFInterceptor.cs
index 8b632ca4..071d7e8d 100644
--- a/sdk/src/Handlers/EntityFramework/EFInterceptor.cs
+++ b/sdk/src/Handlers/EntityFramework/EFInterceptor.cs
@@ -17,9 +17,6 @@
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Diagnostics;
-using Amazon.XRay.Recorder.Core;
-using Amazon.XRay.Recorder.Core.Internal.Entities;
-using Amazon.XRay.Recorder.Core.Exceptions;
using System.Threading;
using System.Threading.Tasks;
@@ -27,22 +24,10 @@ namespace Amazon.XRay.Recorder.Handlers.EntityFramework
{
public class EFInterceptor : DbCommandInterceptor
{
- private readonly AWSXRayRecorder _recorder;
private readonly bool? _collectSqlQueriesOverride;
- public EFInterceptor() : this(AWSXRayRecorder.Instance)
+ public EFInterceptor(bool? collectSqlQueries = null) : base()
{
-
- }
-
- public EFInterceptor(bool? collectSqlQueries = null) : this(AWSXRayRecorder.Instance, collectSqlQueries)
- {
-
- }
-
- public EFInterceptor(AWSXRayRecorder recorder, bool? collectSqlQueries = null) : base()
- {
- _recorder = recorder;
_collectSqlQueriesOverride = collectSqlQueries;
}
@@ -55,7 +40,7 @@ public EFInterceptor(AWSXRayRecorder recorder, bool? collectSqlQueries = null) :
/// Result from .
public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result)
{
- ProcessBeginCommand(eventData);
+ EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride);
return base.ReaderExecuting(command, eventData, result);
}
@@ -68,7 +53,7 @@ public override InterceptionResult ReaderExecuting(DbCommand comma
/// Instance of .
public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
{
- ProcessEndCommand();
+ EFUtil.ProcessEndCommand();
return base.ReaderExecuted(command, eventData, result);
}
@@ -82,7 +67,7 @@ public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEv
/// Task representing the async operation.
public override Task> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
- ProcessBeginCommand(eventData);
+ EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride);
return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
}
@@ -96,7 +81,7 @@ public override Task> ReaderExecutingAsync(DbCo
/// Task representing the async operation.
public override Task ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default)
{
- ProcessEndCommand();
+ EFUtil.ProcessEndCommand();
return base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
}
@@ -107,7 +92,7 @@ public override Task ReaderExecutedAsync(DbCommand command, Comman
/// Instance of .
public override void CommandFailed(DbCommand command, CommandErrorEventData eventData)
{
- ProcessCommandError(eventData);
+ EFUtil.ProcessCommandError(eventData.Exception);
base.CommandFailed(command, eventData);
}
@@ -120,7 +105,7 @@ public override void CommandFailed(DbCommand command, CommandErrorEventData even
/// Task representing the async operation.
public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, CancellationToken cancellationToken = default)
{
- ProcessCommandError(eventData);
+ EFUtil.ProcessCommandError(eventData.Exception);
return base.CommandFailedAsync(command, eventData, cancellationToken);
}
@@ -133,7 +118,7 @@ public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData
/// Task representing the operation.
public override InterceptionResult NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result)
{
- ProcessBeginCommand(eventData);
+ EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride);
return base.NonQueryExecuting(command, eventData, result);
}
@@ -147,7 +132,7 @@ public override InterceptionResult NonQueryExecuting(DbCommand command, Com
/// Task representing the async operation.
public override Task> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
- ProcessBeginCommand(eventData);
+ EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride);
return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken);
}
@@ -160,7 +145,7 @@ public override Task> NonQueryExecutingAsync(DbCommand c
/// Result as integer.
public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result)
{
- ProcessEndCommand();
+ EFUtil.ProcessEndCommand();
return base.NonQueryExecuted(command, eventData, result);
}
@@ -174,7 +159,7 @@ public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData
/// Task representing the async operation.
public override Task NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default)
{
- ProcessEndCommand();
+ EFUtil.ProcessEndCommand();
return base.NonQueryExecutedAsync(command, eventData, result, cancellationToken);
}
@@ -187,7 +172,7 @@ public override Task NonQueryExecutedAsync(DbCommand command, CommandExecut
/// Result from .
public override InterceptionResult
+
@@ -64,6 +64,7 @@
+
@@ -74,8 +75,11 @@
+
+
+
@@ -83,8 +87,8 @@
+
-
diff --git a/sdk/test/UnitTests/EF6Tests.cs b/sdk/test/UnitTests/EF6Tests.cs
new file mode 100644
index 00000000..bf86f378
--- /dev/null
+++ b/sdk/test/UnitTests/EF6Tests.cs
@@ -0,0 +1,186 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License").
+// You may not use this file except in compliance with the License.
+// A copy of the License is located at
+//
+// http://aws.amazon.com/apache2.0
+//
+// or in the "license" file accompanying this file. This file is distributed
+// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the License for the specific language governing
+// permissions and limitations under the License.
+//
+//-----------------------------------------------------------------------------
+
+using Amazon.XRay.Recorder.Core;
+using Amazon.XRay.Recorder.Core.Internal.Entities;
+using Amazon.XRay.Recorder.Handlers.EntityFramework;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Data.Entity.Infrastructure.Interception;
+using System.Data.SQLite;
+
+namespace Amazon.XRay.Recorder.UnitTests
+{
+ [TestClass]
+ public class EF6Tests : TestBase
+ {
+ private SQLiteConnection connection = null;
+ private AWSXRayRecorder recorder = null;
+ private const string connectionString = "data source=:memory:";
+ private const string database = "sqlite";
+ private const string nameSpace = "remote";
+ private const string commandText = "Test command text";
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ recorder = new AWSXRayRecorder();
+ recorder.BeginSegment("Test EF6");
+ connection = new SQLiteConnection(connectionString);
+ connection.Open();
+ }
+
+ [TestCleanup]
+ public new void TestCleanup()
+ {
+ connection.Close();
+ connection.Dispose();
+ recorder.EndSegment();
+ recorder.Dispose();
+ base.TestCleanup();
+ }
+
+ [TestMethod]
+ public void TestEFInterceptorNonQuery()
+ {
+ var efInterceptor = RegisterInterceptor(true);
+
+ try
+ {
+ using (var command = new SQLiteCommand(commandText, connection))
+ {
+ DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor
+ }
+ }
+ catch
+ {
+ // Will throw exception as command text is invalid
+ }
+
+ var segment = recorder.GetEntity() as Segment;
+ Assert.IsTrue(segment.Subsegments.Count != 0);
+
+ var subsegment = segment.Subsegments[0];
+ AssertTraceCollected(subsegment);
+ Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]);
+
+ RemoveInterceptor(efInterceptor);
+ }
+
+ [TestMethod]
+ public void TestEFInterceptorReader()
+ {
+ var efInterceptor = RegisterInterceptor(true);
+
+ try
+ {
+ using (var command = new SQLiteCommand(commandText, connection))
+ {
+ DbInterception.Dispatch.Command.Reader(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor
+ }
+ }
+ catch
+ {
+ // Will throw exception as command text is invalid
+ }
+
+ var segment = recorder.GetEntity() as Segment;
+ Assert.IsTrue(segment.Subsegments.Count != 0);
+
+ var subsegment = segment.Subsegments[0];
+ AssertTraceCollected(subsegment);
+ Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]);
+
+ RemoveInterceptor(efInterceptor);
+ }
+
+ [TestMethod]
+ public void TestEFInterceptorScalar()
+ {
+ var efInterceptor = RegisterInterceptor(true);
+
+ try
+ {
+ using (var command = new SQLiteCommand(commandText, connection))
+ {
+ DbInterception.Dispatch.Command.Scalar(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor
+ }
+ }
+ catch
+ {
+ // Will throw exception as command text is invalid
+ }
+
+ var segment = recorder.GetEntity() as Segment;
+ Assert.IsTrue(segment.Subsegments.Count != 0);
+
+ var subsegment = segment.Subsegments[0];
+ AssertTraceCollected(subsegment);
+ Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]);
+
+ RemoveInterceptor(efInterceptor);
+ }
+
+ [TestMethod]
+ public void TestEFInterceptorNonQueryWithoutQueryText()
+ {
+ var efInterceptor = RegisterInterceptor(false);
+
+ try
+ {
+ using (var command = new SQLiteCommand(commandText, connection))
+ {
+ DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor
+ }
+ }
+ catch
+ {
+ // Will throw exception as command text is invalid
+ }
+
+ var segment = recorder.GetEntity() as Segment;
+ Assert.IsTrue(segment.Subsegments.Count != 0);
+
+ var subsegment = segment.Subsegments[0];
+ AssertTraceCollected(subsegment);
+ Assert.IsFalse(subsegment.Sql.ContainsKey("sanitized_query"));
+
+ RemoveInterceptor(efInterceptor);
+ }
+
+ private EFInterceptor RegisterInterceptor(bool collectSqlQueries)
+ {
+ var efInterceptor = new EFInterceptor(collectSqlQueries);
+ DbInterception.Add(efInterceptor);
+ return efInterceptor;
+ }
+
+ // Remove EFInterceptor from DbInterceptor to avoid duplicate tracing
+ private void RemoveInterceptor(EFInterceptor interceptor)
+ {
+ DbInterception.Remove(interceptor);
+ }
+
+ private void AssertTraceCollected(Subsegment subsegment)
+ {
+ Assert.AreEqual(connection.ConnectionString, subsegment.Sql["connection_string"]);
+ Assert.AreEqual(database, subsegment.Sql["database_type"]);
+ Assert.AreEqual(connection.ServerVersion, subsegment.Sql["database_version"]);
+ Assert.AreEqual(nameSpace, subsegment.Namespace);
+ Assert.IsTrue(subsegment.HasFault);
+ }
+ }
+}
diff --git a/sdk/test/UnitTests/EFUtilTests.cs b/sdk/test/UnitTests/EFUtilTests.cs
index b429ef29..31941fab 100644
--- a/sdk/test/UnitTests/EFUtilTests.cs
+++ b/sdk/test/UnitTests/EFUtilTests.cs
@@ -18,6 +18,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.Common;
using Amazon.XRay.Recorder.Handlers.EntityFramework;
+using System.Data.SQLite;
+using System.Data.SqlClient;
namespace Amazon.XRay.Recorder.UnitTests
{
@@ -90,5 +92,31 @@ public void Test_Get_UserId_FirebirdSql()
object result = EFUtil.GetUserId(builder);
Assert.AreEqual("SYSDBA", result.ToString());
}
+
+ [TestMethod]
+ public void Test_Get_Database_Type_Sqlite()
+ {
+ var connection = new SQLiteConnection();
+ var command = new SQLiteCommand(null, connection);
+ var databaseType = EFUtil.GetDataBaseType(command);
+ Assert.AreEqual("sqlite", databaseType);
+ }
+
+ [TestMethod]
+ public void Test_Get_Database_Type_SqlServer()
+ {
+ var connection = new SqlConnection();
+ var command = new SqlCommand(null, connection);
+ var databaseType = EFUtil.GetDataBaseType(command);
+ Assert.AreEqual("sqlserver", databaseType);
+ }
+
+ [TestMethod]
+ public void Test_Get_Database_Type_EmptyConnection()
+ {
+ var command = new SqlCommand();
+ var databaseType = EFUtil.GetDataBaseType(command);
+ Assert.AreEqual("entityframework", databaseType); // Empty connection will return entityframework by default.
+ }
}
}
\ No newline at end of file
diff --git a/sdk/test/UnitTests/Tools/TestEFContext.cs b/sdk/test/UnitTests/Tools/TestEFContext.cs
index b786f046..607531ed 100644
--- a/sdk/test/UnitTests/Tools/TestEFContext.cs
+++ b/sdk/test/UnitTests/Tools/TestEFContext.cs
@@ -1,6 +1,19 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+//-----------------------------------------------------------------------------
+//
+// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License").
+// You may not use this file except in compliance with the License.
+// A copy of the License is located at
+//
+// http://aws.amazon.com/apache2.0
+//
+// or in the "license" file accompanying this file. This file is distributed
+// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the License for the specific language governing
+// permissions and limitations under the License.
+//
+//-----------------------------------------------------------------------------
using Microsoft.EntityFrameworkCore;