diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/AddFibonacciNumberCommandHandler.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/AddFibonacciNumberCommandHandler.cs
new file mode 100644
index 00000000..879b16ad
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/AddFibonacciNumberCommandHandler.cs
@@ -0,0 +1,98 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Command;
+using RapidField.SolidInstruments.Core.Concurrency;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories;
+using RapidField.SolidInstruments.ObjectComposition;
+using System;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.CommandHandlers
+{
+ ///
+ /// Processes a command that adds a Fibonacci number to the Simulated database.
+ ///
+ public sealed class AddFibonacciNumberCommandHandler : SimulatedCommandHandler
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ public AddFibonacciNumberCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory)
+ : base(mediator, repositoryFactory)
+ {
+ return;
+ }
+
+ ///
+ /// Releases all resources consumed by the current .
+ ///
+ ///
+ /// A value indicating whether or not managed resources should be released.
+ ///
+ protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
+
+ ///
+ /// Processes the specified command.
+ ///
+ ///
+ /// The command to process.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands. Do not process using
+ /// , as doing so will generally result in infinite-looping.
+ ///
+ ///
+ /// An object that provides access to data access repositories.
+ ///
+ ///
+ /// A token that represents and manages contextual thread safety.
+ ///
+ protected override void Process(AddFibonacciNumberCommand command, ICommandMediator mediator, IFactoryProducedInstanceGroup repositories, IConcurrencyControlToken controlToken)
+ {
+ var fibonacciNumberSeries = NumberSeries.Named.Fibonacci;
+ var numberRepository = repositories.Get();
+ var number = numberRepository.FindByValue(command.NumberValue);
+
+ if (number is null)
+ {
+ number = new Number()
+ {
+ Identifier = Guid.NewGuid(),
+ Value = command.NumberValue
+ };
+
+ numberRepository.Add(number);
+ }
+
+ var numberSeriesNumberRespository = repositories.Get();
+ var numberSeriesNumber = numberSeriesNumberRespository.FindWhere(entity => entity.Number.Value == number.Value && entity.NumberSeriesIdentifier == fibonacciNumberSeries.Identifier).SingleOrDefault();
+
+ if (numberSeriesNumber is null)
+ {
+ numberSeriesNumber = new NumberSeriesNumber()
+ {
+ Identifier = Guid.NewGuid(),
+ Number = number,
+ NumberIdentifier = number.Identifier,
+ NumberSeriesIdentifier = fibonacciNumberSeries.Identifier
+ };
+
+ numberSeriesNumberRespository.Add(numberSeriesNumber);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/GetFibonacciNumberValuesCommandHandler.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/GetFibonacciNumberValuesCommandHandler.cs
new file mode 100644
index 00000000..66aab7b3
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/CommandHandlers/GetFibonacciNumberValuesCommandHandler.cs
@@ -0,0 +1,74 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Command;
+using RapidField.SolidInstruments.Core.Concurrency;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories;
+using RapidField.SolidInstruments.ObjectComposition;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.CommandHandlers
+{
+ ///
+ /// Processes a command that gets all of the Fibonacci number values from the Simulated database.
+ ///
+ public sealed class GetFibonacciNumberValuesCommandHandler : SimulatedCommandHandler>
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ public GetFibonacciNumberValuesCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory)
+ : base(mediator, repositoryFactory)
+ {
+ return;
+ }
+
+ ///
+ /// Releases all resources consumed by the current .
+ ///
+ ///
+ /// A value indicating whether or not managed resources should be released.
+ ///
+ protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
+
+ ///
+ /// Processes the specified command.
+ ///
+ ///
+ /// The command to process.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands. Do not process using
+ /// , as doing so will generally result in infinite-looping.
+ ///
+ ///
+ /// An object that provides access to data access repositories.
+ ///
+ ///
+ /// A token that represents and manages contextual thread safety.
+ ///
+ ///
+ /// The result that is emitted when processing the command.
+ ///
+ protected sealed override IEnumerable Process(GetFibonacciNumberValuesCommand command, ICommandMediator mediator, IFactoryProducedInstanceGroup repositories, IConcurrencyControlToken controlToken)
+ {
+ var numberSeriesNumberRepository = repositories.Get();
+ return numberSeriesNumberRepository.FindWhere(entity => entity.NumberSeries.Identifier == NumberSeries.Named.Fibonacci.Identifier).Select(entity => entity.Number.Value).ToList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/AddFibonacciNumberCommand.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/AddFibonacciNumberCommand.cs
new file mode 100644
index 00000000..8f4c7990
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/AddFibonacciNumberCommand.cs
@@ -0,0 +1,41 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess;
+using System;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands
+{
+ ///
+ /// Represents a data access command that adds a specified numeric value to the Fibonacci series.
+ ///
+ [DataContract]
+ public sealed class AddFibonacciNumberCommand : DataAccessCommand
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The value of the Fibonacci number that is added to the series.
+ ///
+ [DebuggerHidden]
+ internal AddFibonacciNumberCommand(Int64 numberValue)
+ : base()
+ {
+ NumberValue = numberValue;
+ }
+
+ ///
+ /// Gets or sets the value of the Fibonacci number that is added to the series.
+ ///
+ [DataMember]
+ public Int64 NumberValue
+ {
+ get;
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/GetFibonacciNumberValuesCommand.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/GetFibonacciNumberValuesCommand.cs
new file mode 100644
index 00000000..2382c497
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Commands/GetFibonacciNumberValuesCommand.cs
@@ -0,0 +1,29 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands
+{
+ ///
+ /// Represents a data access command that returns the numeric values for the Fibonacci series.
+ ///
+ [DataContract]
+ public sealed class GetFibonacciNumberValuesCommand : DataAccessCommand>
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [DebuggerHidden]
+ internal GetFibonacciNumberValuesCommand()
+ : base()
+ {
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/Number.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/Number.cs
new file mode 100644
index 00000000..162de452
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/Number.cs
@@ -0,0 +1,79 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Core.ArgumentValidation;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities
+{
+ ///
+ /// Represents an integer number.
+ ///
+ public sealed class Number : INumber
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [DebuggerHidden]
+ internal Number()
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A model that is used to hydrate the new object.
+ ///
+ [DebuggerHidden]
+ internal Number(INumber model)
+ : this(model.Identifier, model.Value)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A unique identifier for the entity.
+ ///
+ ///
+ /// The value of the number.
+ ///
+ ///
+ /// is equal to .
+ ///
+ [DebuggerHidden]
+ private Number(Guid identifier, Int64 value)
+ {
+ Identifier = identifier.RejectIf().IsEqualToValue(Guid.Empty, nameof(identifier));
+ Value = value;
+ }
+
+ ///
+ /// Gets or sets a unique identifier for the entity.
+ ///
+ [Key]
+ public Guid Identifier
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the value of the number.
+ ///
+ [Required]
+ public Int64 Value
+ {
+ get;
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeries.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeries.cs
new file mode 100644
index 00000000..6939a746
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeries.cs
@@ -0,0 +1,102 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Core;
+using RapidField.SolidInstruments.Core.ArgumentValidation;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities
+{
+ ///
+ /// Represents a sequential series of integer numbers.
+ ///
+ public sealed class NumberSeries : INumberSeries
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [DebuggerHidden]
+ internal NumberSeries()
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A model that is used to hydrate the new object.
+ ///
+ [DebuggerHidden]
+ internal NumberSeries(INumberSeries model)
+ : this(model.Identifier, model.Name)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A unique identifier for the entity.
+ ///
+ ///
+ /// The name of the series.
+ ///
+ ///
+ /// is empty.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// is equal to .
+ ///
+ [DebuggerHidden]
+ private NumberSeries(Guid identifier, String name)
+ {
+ Identifier = identifier.RejectIf().IsEqualToValue(Guid.Empty, nameof(identifier));
+ Name = name.RejectIf().IsNullOrEmpty(nameof(name));
+ }
+
+ ///
+ /// Gets or sets a unique identifier for the entity.
+ ///
+ [Key]
+ public Guid Identifier
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the name of the series.
+ ///
+ [Required]
+ public String Name
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Contains a collection of known records.
+ ///
+ internal static class Named
+ {
+ ///
+ /// Represents the Fibonacci number series.
+ ///
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ internal static NumberSeries Fibonacci => new NumberSeries()
+ {
+ Identifier = Guid.Parse("1100d8c5-a70c-4db2-833d-33638e453082"),
+ Name = "Fibonacci"
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeriesNumber.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeriesNumber.cs
new file mode 100644
index 00000000..d16cde68
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Entities/NumberSeriesNumber.cs
@@ -0,0 +1,115 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Core.ArgumentValidation;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Diagnostics;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities
+{
+ ///
+ /// Represents an integer number belonging to a specific number series.
+ ///
+ public sealed class NumberSeriesNumber : INumberSeriesNumber
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [DebuggerHidden]
+ internal NumberSeriesNumber()
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A model that is used to hydrate the new object.
+ ///
+ [DebuggerHidden]
+ internal NumberSeriesNumber(INumberSeriesNumber model)
+ : this(model.Identifier, model.NumberIdentifier, model.NumberSeriesIdentifier)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A unique identifier for the entity.
+ ///
+ ///
+ /// A unique identifier for the associated number.
+ ///
+ ///
+ /// A unique identifier for the associated number series.
+ ///
+ ///
+ /// is equal to -or- is equal
+ /// to -or- is equal to .
+ ///
+ [DebuggerHidden]
+ private NumberSeriesNumber(Guid identifier, Guid numberIdentifier, Guid numberSeriesIdentifier)
+ {
+ Identifier = identifier.RejectIf().IsEqualToValue(Guid.Empty, nameof(identifier));
+ NumberIdentifier = numberIdentifier.RejectIf().IsEqualToValue(Guid.Empty, nameof(numberIdentifier));
+ NumberSeriesIdentifier = numberSeriesIdentifier.RejectIf().IsEqualToValue(Guid.Empty, nameof(numberSeriesIdentifier));
+ }
+
+ ///
+ /// Gets or sets a unique identifier for the entity.
+ ///
+ [Key]
+ public Guid Identifier
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the associated number.
+ ///
+ [ForeignKey(nameof(NumberIdentifier))]
+ public Number Number
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets a unique identifier for the associated number.
+ ///
+ [Required]
+ public Guid NumberIdentifier
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the associated number series.
+ ///
+ [ForeignKey(nameof(NumberSeriesIdentifier))]
+ public NumberSeries NumberSeries
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets a unique identifier for the associated number series.
+ ///
+ [Required]
+ public Guid NumberSeriesIdentifier
+ {
+ get;
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkCommandHandlerTests.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkCommandHandlerTests.cs
index f329a913..ed0da5c4 100644
--- a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkCommandHandlerTests.cs
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkCommandHandlerTests.cs
@@ -6,9 +6,9 @@
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RapidField.SolidInstruments.Command;
-using RapidField.SolidInstruments.Example.DatabaseModel;
-using RapidField.SolidInstruments.Example.DatabaseModel.CommandHandlers;
-using RapidField.SolidInstruments.Example.DatabaseModel.Commands;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.CommandHandlers;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands;
using RapidField.SolidInstruments.TextEncoding;
using System;
@@ -34,9 +34,9 @@ public void FunctionalLifeSpanTest_ShouldProduceDesiredResults()
var scope = engine.Container.CreateScope();
var commandMediator = scope.Resolve();
- using (var context = new ExampleInMemoryContext(configuration, databaseName).WithTestData())
+ using (var context = new SimulatedInMemoryContext(configuration, databaseName).WithTestData())
{
- using (var repositoryFactory = new ExampleRepositoryFactory(context, configuration))
+ using (var repositoryFactory = new SimulatedRepositoryFactory(context, configuration))
{
using (var commandHandler = new GetFibonacciNumberValuesCommandHandler(commandMediator, repositoryFactory))
{
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkRepositoryTests.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkRepositoryTests.cs
index b9ce5fce..991cd299 100644
--- a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkRepositoryTests.cs
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/EntityFrameworkRepositoryTests.cs
@@ -5,8 +5,8 @@
using FluentAssertions;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using RapidField.SolidInstruments.Example.DatabaseModel;
-using RapidField.SolidInstruments.Example.DatabaseModel.Repositories;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories;
using RapidField.SolidInstruments.TextEncoding;
using System;
using System.Linq;
@@ -25,7 +25,7 @@ public void FunctionalLifeSpanTest_ShouldProduceDesiredResults()
var fibonacciNumberSeriesName = "Fibonacci";
var fibonacciNumberSeriesValues = new Int64[] { 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
- using (var context = new ExampleInMemoryContext(configuration, databaseName).WithTestData())
+ using (var context = new SimulatedInMemoryContext(configuration, databaseName).WithTestData())
{
using (var numberSeriesRepository = new NumberSeriesRepository(context))
{
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberExtensions.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberExtensions.cs
new file mode 100644
index 00000000..5abbf612
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberExtensions.cs
@@ -0,0 +1,26 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Extensions
+{
+ ///
+ /// Extends the interface with type conversion features.
+ ///
+ public static class INumberExtensions
+ {
+ ///
+ /// Converts the specified model to a messaging model.
+ ///
+ ///
+ /// The current .
+ ///
+ ///
+ /// The converted object.
+ ///
+ public static Number ToSimulatedDatabaseEntity(this INumber target) => new Number(target);
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesExtensions.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesExtensions.cs
new file mode 100644
index 00000000..68b5ad64
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesExtensions.cs
@@ -0,0 +1,26 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Extensions
+{
+ ///
+ /// Extends the interface with type conversion features.
+ ///
+ public static class INumberSeriesExtensions
+ {
+ ///
+ /// Converts the specified model to a messaging model.
+ ///
+ ///
+ /// The current .
+ ///
+ ///
+ /// The converted object.
+ ///
+ public static NumberSeries ToSimulatedDatabaseEntity(this INumberSeries target) => new NumberSeries(target);
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesNumberExtensions.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesNumberExtensions.cs
new file mode 100644
index 00000000..a978e6e6
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Extensions/INumberSeriesNumberExtensions.cs
@@ -0,0 +1,26 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Extensions
+{
+ ///
+ /// Extends the interface with type conversion features.
+ ///
+ public static class INumberSeriesNumberExtensions
+ {
+ ///
+ /// Converts the specified model to a messaging model.
+ ///
+ ///
+ /// The current .
+ ///
+ ///
+ /// The converted object.
+ ///
+ public static NumberSeriesNumber ToSimulatedDatabaseEntity(this INumberSeriesNumber target) => new NumberSeriesNumber(target);
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumber.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumber.cs
new file mode 100644
index 00000000..7cf8a14c
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumber.cs
@@ -0,0 +1,30 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using System;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models
+{
+ ///
+ /// Represents an integer number.
+ ///
+ public interface INumber
+ {
+ ///
+ /// Gets a unique identifier for the entity.
+ ///
+ public Guid Identifier
+ {
+ get;
+ }
+
+ ///
+ /// Gets the value of the number.
+ ///
+ public Int64 Value
+ {
+ get;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeries.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeries.cs
new file mode 100644
index 00000000..b20e651c
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeries.cs
@@ -0,0 +1,30 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using System;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models
+{
+ ///
+ /// Represents a sequential series of integer numbers.
+ ///
+ public interface INumberSeries
+ {
+ ///
+ /// Gets a unique identifier for the entity.
+ ///
+ public Guid Identifier
+ {
+ get;
+ }
+
+ ///
+ /// Gets the name of the series.
+ ///
+ public String Name
+ {
+ get;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeriesNumber.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeriesNumber.cs
new file mode 100644
index 00000000..2e56d955
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Models/INumberSeriesNumber.cs
@@ -0,0 +1,38 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using System;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Models
+{
+ ///
+ /// Represents an integer number belonging to a specific number series.
+ ///
+ public interface INumberSeriesNumber
+ {
+ ///
+ /// Gets a unique identifier for the entity.
+ ///
+ public Guid Identifier
+ {
+ get;
+ }
+
+ ///
+ /// Gets a unique identifier for the associated number.
+ ///
+ public Guid NumberIdentifier
+ {
+ get;
+ }
+
+ ///
+ /// Gets a unique identifier for the associated number series.
+ ///
+ public Guid NumberSeriesIdentifier
+ {
+ get;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.csproj b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.csproj
index a9797c8f..ba3492ee 100644
--- a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.csproj
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.csproj
@@ -24,9 +24,11 @@ Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in
-
+
+
+
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberRepository.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberRepository.cs
new file mode 100644
index 00000000..ad4ef7c0
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberRepository.cs
@@ -0,0 +1,56 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using System;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories
+{
+ ///
+ /// Represents a repository for the entity type.
+ ///
+ public sealed class NumberRepository : EntityFrameworkRepository
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session for the repository.
+ ///
+ ///
+ /// is .
+ ///
+ public NumberRepository(SimulatedContext context)
+ : base(context)
+ {
+ return;
+ }
+
+ ///
+ /// Finds the with the specified identifier.
+ ///
+ ///
+ /// The identifier to find.
+ ///
+ ///
+ /// The with the specified value, or if the is not
+ /// found.
+ ///
+ public Number FindByIdentifier(Guid identifier) => FindWhere(entity => entity.Identifier == identifier).SingleOrDefault();
+
+ ///
+ /// Finds the with the specified value.
+ ///
+ ///
+ /// The value to find.
+ ///
+ ///
+ /// The with the specified value, or if the is not
+ /// found.
+ ///
+ public Number FindByValue(Int64 value) => FindWhere(entity => entity.Value == value).SingleOrDefault();
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesNumberRepository.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesNumberRepository.cs
new file mode 100644
index 00000000..bda6ab6b
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesNumberRepository.cs
@@ -0,0 +1,44 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using System;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories
+{
+ ///
+ /// Represents a repository for the entity type.
+ ///
+ public sealed class NumberSeriesNumberRepository : EntityFrameworkRepository
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session for the repository.
+ ///
+ ///
+ /// is .
+ ///
+ public NumberSeriesNumberRepository(SimulatedContext context)
+ : base(context)
+ {
+ return;
+ }
+
+ ///
+ /// Finds the with the specified identifier.
+ ///
+ ///
+ /// The identifier to find.
+ ///
+ ///
+ /// The with the specified value, or if the
+ /// is not found.
+ ///
+ public NumberSeriesNumber FindByIdentifier(Guid identifier) => FindWhere(entity => entity.Identifier == identifier).SingleOrDefault();
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesRepository.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesRepository.cs
new file mode 100644
index 00000000..e33865a4
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/Repositories/NumberSeriesRepository.cs
@@ -0,0 +1,56 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using System;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories
+{
+ ///
+ /// Represents a repository for the entity type.
+ ///
+ public sealed class NumberSeriesRepository : EntityFrameworkRepository
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session for the repository.
+ ///
+ ///
+ /// is .
+ ///
+ public NumberSeriesRepository(SimulatedContext context)
+ : base(context)
+ {
+ return;
+ }
+
+ ///
+ /// Finds the with the specified identifier.
+ ///
+ ///
+ /// The identifier to find.
+ ///
+ ///
+ /// The with the specified identifier, or if the
+ /// is not found.
+ ///
+ public NumberSeries FindByIdentifier(Guid identifier) => FindWhere(entity => entity.Identifier == identifier).SingleOrDefault();
+
+ ///
+ /// Finds the with the specified name.
+ ///
+ ///
+ /// The name to find.
+ ///
+ ///
+ /// The with the specified name, or if the
+ /// is not found.
+ ///
+ public NumberSeries FindByName(String name) => FindWhere(entity => entity.Name == name).SingleOrDefault();
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommandHandler.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommandHandler.cs
new file mode 100644
index 00000000..2c4717e9
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommandHandler.cs
@@ -0,0 +1,135 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Command;
+using RapidField.SolidInstruments.DataAccess;
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using System;
+using System.Data;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Processes Simulated data access commands.
+ ///
+ ///
+ /// The type of the data access command that is processed by the handler.
+ ///
+ public abstract class SimulatedCommandHandler : EntityFrameworkCommandHandler
+ where TCommand : class, IDataAccessCommand
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ protected SimulatedCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory)
+ : base(mediator, repositoryFactory)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// The isolation level for the transaction, or to use the database default. The
+ /// default value is .
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ protected SimulatedCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory, IsolationLevel isolationLevel)
+ : base(mediator, repositoryFactory, isolationLevel)
+ {
+ return;
+ }
+
+ ///
+ /// Releases all resources consumed by the current .
+ ///
+ ///
+ /// A value indicating whether or not managed resources should be released.
+ ///
+ protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
+ }
+
+ ///
+ /// Processes Simulated data access commands.
+ ///
+ ///
+ /// The type of the data access command that is processed by the handler.
+ ///
+ ///
+ /// The type of the result that is emitted by the handler when processing a data access command.
+ ///
+ public abstract class SimulatedCommandHandler : EntityFrameworkCommandHandler
+ where TCommand : class, IDataAccessCommand
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ protected SimulatedCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory)
+ : base(mediator, repositoryFactory)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A processing intermediary that is used to process sub-commands.
+ ///
+ ///
+ /// The factory that produces data access repositories for the handler.
+ ///
+ ///
+ /// The isolation level for the transaction, or to use the database default. The
+ /// default value is .
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ protected SimulatedCommandHandler(ICommandMediator mediator, SimulatedRepositoryFactory repositoryFactory, IsolationLevel isolationLevel)
+ : base(mediator, repositoryFactory, isolationLevel)
+ {
+ return;
+ }
+
+ ///
+ /// Releases all resources consumed by the current .
+ ///
+ ///
+ /// A value indicating whether or not managed resources should be released.
+ ///
+ protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommands.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommands.cs
new file mode 100644
index 00000000..3221b99b
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedCommands.cs
@@ -0,0 +1,34 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.Core;
+using RapidField.SolidInstruments.DataAccess;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands;
+using System;
+using System.Collections.Generic;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Exposes a collection of data access commands for the Simulated database.
+ ///
+ public static class SimulatedCommands
+ {
+ ///
+ /// Creates a data access command that adds a specified numeric value to the Fibonacci series.
+ ///
+ ///
+ /// The value of the Fibonacci number that is added to the series.
+ ///
+ public static IDataAccessCommand AddFibonacciNumber(Int64 numberValue) => new AddFibonacciNumberCommand(numberValue);
+
+ ///
+ /// Creates a data access command that returns the numeric values for the Fibonacci series.
+ ///
+ ///
+ /// The numeric values for the Fibonacci series.
+ ///
+ public static IDataAccessCommand> GetFibonacciNumberValues() => new GetFibonacciNumberValuesCommand();
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedContext.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedContext.cs
new file mode 100644
index 00000000..fcb08631
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedContext.cs
@@ -0,0 +1,181 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using RapidField.SolidInstruments.Core;
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using System;
+using System.Configuration;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Represents a connection to a prototypical database.
+ ///
+ public class SimulatedContext : ConfiguredContext
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// The constructor was unable to determine the appropriate connection type by evaluating the connection string.
+ ///
+ public SimulatedContext(IConfiguration applicationConfiguration)
+ : base(applicationConfiguration)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// The database type of the backing database, or to determine the connection
+ /// type dynamically based on the format of the connection string.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// is equal to and the constructor was
+ /// unable to determine the appropriate connection type by evaluating the connection string.
+ ///
+ public SimulatedContext(IConfiguration applicationConfiguration, ContextDatabaseType databaseType)
+ : base(applicationConfiguration, databaseType)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// The database type of the backing database, or to determine the connection
+ /// type dynamically based on the format of the connection string.
+ ///
+ ///
+ /// The name of the backing database, which matches the associated connection string key in
+ /// . The default value is equal to the context's type name with "Context"
+ /// trimmed from the end, if found.
+ ///
+ ///
+ /// is empty.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ ///
+ /// is equal to and the constructor was
+ /// unable to determine the appropriate connection type by evaluating the connection string.
+ ///
+ public SimulatedContext(IConfiguration applicationConfiguration, ContextDatabaseType databaseType, String databaseName)
+ : base(applicationConfiguration, databaseType, databaseName)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// The database type of the backing database, or to determine the connection
+ /// type dynamically based on the format of the connection string.
+ ///
+ ///
+ /// The query result tracking behavior for the context. The default value is .
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// is equal to and the constructor was
+ /// unable to determine the appropriate connection type by evaluating the connection string.
+ ///
+ public SimulatedContext(IConfiguration applicationConfiguration, ContextDatabaseType databaseType, QueryTrackingBehavior trackingBehavior)
+ : base(applicationConfiguration, databaseType, trackingBehavior)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// The database type of the backing database, or to determine the connection
+ /// type dynamically based on the format of the connection string.
+ ///
+ ///
+ /// The name of the backing database, which matches the associated connection string key in
+ /// . The default value is equal to the context's type name with "Context"
+ /// trimmed from the end, if found.
+ ///
+ ///
+ /// The query result tracking behavior for the context. The default value is .
+ ///
+ ///
+ /// is empty.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ ///
+ /// is equal to and the constructor was
+ /// unable to determine the appropriate connection type by evaluating the connection string.
+ ///
+ public SimulatedContext(IConfiguration applicationConfiguration, ContextDatabaseType databaseType, String databaseName, QueryTrackingBehavior trackingBehavior)
+ : base(applicationConfiguration, databaseType, databaseName, trackingBehavior)
+ {
+ return;
+ }
+
+ ///
+ /// Gets or sets a persistent collection of records.
+ ///
+ public DbSet Numbers
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets a persistent collection of records.
+ ///
+ public DbSet NumberSeriesNumbers
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets a persistent collection of records.
+ ///
+ public DbSet NumerSeries
+ {
+ get;
+ set;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedDatabaseModelDependencyModule.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedDatabaseModelDependencyModule.cs
new file mode 100644
index 00000000..080bb292
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedDatabaseModelDependencyModule.cs
@@ -0,0 +1,56 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using RapidField.SolidInstruments.DataAccess.DotNetNative.Extensions;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.CommandHandlers;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Commands;
+using RapidField.SolidInstruments.InversionOfControl.DotNetNative;
+using System;
+using System.Collections.Generic;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Encapsulates configuration for Simulated database model dependencies.
+ ///
+ public sealed class SimulatedDatabaseModelDependencyModule : DotNetNativeDependencyModule
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// is .
+ ///
+ public SimulatedDatabaseModelDependencyModule(IConfiguration applicationConfiguration)
+ : base(applicationConfiguration)
+ {
+ return;
+ }
+
+ ///
+ /// Configures the module.
+ ///
+ ///
+ /// An object that configures containers.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ protected override void Configure(ServiceCollection configurator, IConfiguration applicationConfiguration)
+ {
+ // Register unit-of-work types.
+ configurator.AddScoped(provider => new SimulatedInMemoryContext(provider.GetService(), "Simulated"));
+ configurator.AddScoped();
+
+ // Register data access command handlers.
+ configurator.AddDataAccessCommandHandler();
+ configurator.AddDataAccessCommandHandler, GetFibonacciNumberValuesCommandHandler>();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedInMemoryContext.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedInMemoryContext.cs
new file mode 100644
index 00000000..5f0a469e
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedInMemoryContext.cs
@@ -0,0 +1,123 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.Configuration;
+using RapidField.SolidInstruments.Core;
+using RapidField.SolidInstruments.Core.ArgumentValidation;
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Entities;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories;
+using System;
+using System.Diagnostics;
+using System.Linq;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Represents a connection to a prototypical, in-memory database.
+ ///
+ public sealed class SimulatedInMemoryContext : SimulatedContext
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// The name of the backing database, which matches the associated connection string key in
+ /// .
+ ///
+ ///
+ /// is empty.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ public SimulatedInMemoryContext(IConfiguration applicationConfiguration, String databaseName)
+ : base(applicationConfiguration, ContextDatabaseType.InMemory, databaseName.RejectIf().IsNullOrEmpty(nameof(databaseName)))
+ {
+ return;
+ }
+
+ ///
+ /// Populates the current with test data.
+ ///
+ ///
+ /// The current with test data.
+ ///
+ [DebuggerHidden]
+ internal SimulatedInMemoryContext WithTestData()
+ {
+ var fibonacciNumberSeriesValues = new Int64[] { 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
+
+ using (var numberRepository = new NumberRepository(this))
+ {
+ for (var i = 0; i <= 100; i++)
+ {
+ var number = new Number()
+ {
+ Identifier = Guid.NewGuid(),
+ Value = i
+ };
+
+ numberRepository.Add(number);
+ }
+
+ SaveChanges();
+
+ using (var numberSeriesRepository = new NumberSeriesRepository(this))
+ {
+ numberSeriesRepository.Add(NumberSeries.Named.Fibonacci);
+ SaveChanges();
+
+ using (var numberSeriesNumberRepository = new NumberSeriesNumberRepository(this))
+ {
+ var fibonacciNumbers = numberRepository.FindWhere(entity => fibonacciNumberSeriesValues.Contains(entity.Value));
+
+ foreach (var fibonacciNumber in fibonacciNumbers)
+ {
+ var fibonacciNumberSeriesNumber = new NumberSeriesNumber()
+ {
+ Identifier = Guid.NewGuid(),
+ NumberIdentifier = fibonacciNumber.Identifier,
+ NumberSeriesIdentifier = NumberSeries.Named.Fibonacci.Identifier
+ };
+
+ numberSeriesNumberRepository.Add(fibonacciNumberSeriesNumber);
+ }
+
+ SaveChanges();
+ }
+ }
+ }
+
+ return this;
+ }
+
+ ///
+ /// Configures the in-memory database to be used for this context.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// A builder that is used to create or modify options for this context.
+ ///
+ protected sealed override void OnConfiguringInMemory(IConfiguration applicationConfiguration, InMemoryDbContextOptionsBuilder optionsBuilder) => base.OnConfiguringInMemory(applicationConfiguration, optionsBuilder);
+
+ ///
+ /// Configures the SQL Server database to be used for this context.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// A builder that is used to create or modify options for this context.
+ ///
+ protected sealed override void OnConfiguringSqlServer(IConfiguration applicationConfiguration, SqlServerDbContextOptionsBuilder optionsBuilder) => throw new InvalidOperationException();
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedRepositoryFactory.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedRepositoryFactory.cs
new file mode 100644
index 00000000..41c15712
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedRepositoryFactory.cs
@@ -0,0 +1,67 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using Microsoft.Extensions.Configuration;
+using RapidField.SolidInstruments.DataAccess;
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests.Repositories;
+using RapidField.SolidInstruments.ObjectComposition;
+using System;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Encapsulates creation of new that map to Simulated database entities.
+ ///
+ public sealed class SimulatedRepositoryFactory : EntityFrameworkRepositoryFactory
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session that is used by the produced repositories.
+ ///
+ ///
+ /// is .
+ ///
+ public SimulatedRepositoryFactory(SimulatedContext context)
+ : base(context)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session that is used by the produced repositories.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// is -or- is
+ /// .
+ ///
+ public SimulatedRepositoryFactory(SimulatedContext context, IConfiguration applicationConfiguration)
+ : base(context, applicationConfiguration)
+ {
+ return;
+ }
+
+ ///
+ /// Configures the current .
+ ///
+ ///
+ /// Configuration information for the current .
+ ///
+ ///
+ /// The database session that is used by the produced repositories.
+ ///
+ protected override void Configure(ObjectFactoryConfiguration configuration, SimulatedContext context) => configuration.ProductionFunctions
+ .Add(() => new NumberRepository(context))
+ .Add(() => new NumberSeriesNumberRepository(context))
+ .Add(() => new NumberSeriesRepository(context));
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedSqlServerContext.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedSqlServerContext.cs
new file mode 100644
index 00000000..88eed889
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedSqlServerContext.cs
@@ -0,0 +1,55 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.Configuration;
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using System;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Represents a connection to a prototypical, SQL Server database.
+ ///
+ public sealed class SimulatedSqlServerContext : SimulatedContext
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// is .
+ ///
+ public SimulatedSqlServerContext(IConfiguration applicationConfiguration)
+ : base(applicationConfiguration, ContextDatabaseType.SqlServer, QueryTrackingBehavior.TrackAll)
+ {
+ return;
+ }
+
+ ///
+ /// Configures the in-memory database to be used for this context.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// A builder that is used to create or modify options for this context.
+ ///
+ protected sealed override void OnConfiguringInMemory(IConfiguration applicationConfiguration, InMemoryDbContextOptionsBuilder optionsBuilder) => throw new InvalidOperationException();
+
+ ///
+ /// Configures the SQL Server database to be used for this context.
+ ///
+ ///
+ /// Configuration information for the application.
+ ///
+ ///
+ /// A builder that is used to create or modify options for this context.
+ ///
+ protected sealed override void OnConfiguringSqlServer(IConfiguration applicationConfiguration, SqlServerDbContextOptionsBuilder optionsBuilder) => base.OnConfiguringSqlServer(applicationConfiguration, optionsBuilder);
+ }
+}
\ No newline at end of file
diff --git a/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedTransaction.cs b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedTransaction.cs
new file mode 100644
index 00000000..0b7e9ee5
--- /dev/null
+++ b/test/RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests/SimulatedTransaction.cs
@@ -0,0 +1,56 @@
+// =================================================================================================================================
+// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+// =================================================================================================================================
+
+using RapidField.SolidInstruments.DataAccess.EntityFramework;
+using System;
+using System.Data;
+
+namespace RapidField.SolidInstruments.DataAccess.EntityFramework.UnitTests
+{
+ ///
+ /// Represents a prototypical, in-memory database transaction.
+ ///
+ public sealed class SimulatedTransaction : EntityFrameworkTransaction
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session for the transaction.
+ ///
+ ///
+ /// has outstanding changes tracked against it.
+ ///
+ ///
+ /// is .
+ ///
+ public SimulatedTransaction(SimulatedContext context)
+ : base(context)
+ {
+ return;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The database session for the transaction.
+ ///
+ ///
+ /// The isolation level for the transaction, or to use the database default. The
+ /// default value is .
+ ///
+ ///
+ /// has outstanding changes tracked against it.
+ ///
+ ///
+ /// is .
+ ///
+ public SimulatedTransaction(SimulatedContext context, IsolationLevel isolationLevel)
+ : base(context, isolationLevel)
+ {
+ return;
+ }
+ }
+}
\ No newline at end of file