Click here to Skip to main content
15,881,657 members
Articles / All Topics

Using Entity Framework and the Store Procedure Framework To Achieve CQRS - Part #4

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
26 Aug 2016CPOL2 min read 5.4K   1   2
This article follows on from Part3 where we built the CommandStack leveraging EntityFramework andprepared to persist an order and some of its associated data to the database. In thisarticle we will shift our focus to the the client, (well our Integration Tests!) andcreate a test that creates an orde

This article follows on from Part 3 where we built the CommandStack leveraging EntityFramework and prepared to persist an order and some of its associated data to the database. In this article we will shift our focus to the the client, (well our Integration Tests!) and create a test that creates an order, persists it using the CommandStack and reads it back out with the QueryStack.

Since Part 2 I have renamed ReadModelTests to be OrderServiceTests as that now better represents what we are testing. We do need to make a tweak to the "dependency injection" mocker, the *Defaults* class before we can add any tests. Please bear in mind the Defaults class is just to new-up some of our objects. Normally i would use the Ninject DI framework for this purpose. 
 

C#
public static class Defaults
{
    private readonly static string DefaultConnectionString = Properties.Settings.Default.DefaultConnection;

    private static ReadContext DefaultContext
    {
        get
        {
            return new ReadContext(DefaultConnectionString);
        }
    }

    public static OrderReadModel DefaultOrderReadModel
    {
        get
        {
            return new OrderReadModel(DefaultContext);
        }
    }

    public static OrderService DefaultOrderService
    {
        get
        {
            return new OrderService(DefaultOrderReadModel, DefaultUnitOfWork);
        }
    }

    public static UnitOfWork DefaultUnitOfWork
    {
        get
        {
            return new UnitOfWork(DefaultConnectionString);
        }
    }
}

I'm not going to go into each of the tests I have written (however they are all in the source code on my GitHub repository. We will only focus on one test that will show off our Command Stack. We will create an command for the new order for an existing customer, and two of the products in the database. We will use the service to generated a new order Id and then create the CreateNewOrderForCustomerWithProductsCommand. (IDEA: This command maybe better named as `CreateNewOrderWithProductsForCustomerCommand`?). Once the command is created we will use a new `TransactionScope` so we can roll back the transaction and leave the database in the state we found it after each run of the test. Once inside the transaction we will use the OrderService to create the order. We will then use the OrderReadModel (from the second post in this series) to read the new order details back out so we may check all of the order details are correct once we have rolled back the transaction.

C#
[TestMethod]
public void CreateNewOrderForCustomerWithProducts_WhenGivenValidProducts_CreatesAnOrder()
{
    // ARRANGE
    var customerId = new Guid("17e3a22e-07e5-4ab2-8e62-1b15f9916909");
    var productsOnOrder = new List<int> { 8, 9 };
    const string customerOrderNumber = "00123";
    var orderService = Defaults.DefaultOrderService;
    var orderId = orderService.GenerateNewOrderId();
    var command = new CreateNewOrderForCustomerWithProductsCommand
    {
        OrderId = orderId,
        CustomerId = customerId,
        ProductsOnOrder = productsOnOrder,
        CustomerOrderNumber = customerOrderNumber
    };
    OrderDetailsModel actual;

    // ACT
    using (var transaction = new TransactionScope())
    {
        orderService.CreateNewOrderForCustomerWithProducts(command);

        actual = orderService.GetOrderForId(orderId);

        transaction.Dispose();
    }

    // ASSERT
    Assert.IsNotNull(actual);
    Assert.IsNotNull(actual.ProductsOnOrder);
    Assert.AreEqual(2, actual.ProductsOnOrder.Count);

    var actualProduct1 = actual.ProductsOnOrder.FirstOrDefault(p => p.ProductId == 8);
    Assert.IsNotNull(actualProduct1);
    Assert.AreEqual(14.99M, actualProduct1.PurchasePrice);

    var actualProduct2 = actual.ProductsOnOrder.FirstOrDefault(p => p.ProductId == 9);
    Assert.IsNotNull(actualProduct2);
    Assert.AreEqual(29.99M, actualProduct2.PurchasePrice);
}

Summary

So there we have it. A small solution showing how you can leverage the *StoredProcedureFramework* and *EntityFramework* to achieve CQRS in a .Net application. All of the code is available in [this GitHub]() repository.

Part 1 Setting up the data
Part 2 Querying the database using the QueryStack
Part 3 Writing to the database using the CommandStack

 

 

 

Disclaimer

I am the author of the Stored Procedure Framework.

 

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United Kingdom United Kingdom
Duane has worked in a commercial software development environment for 9 years, with all but three for a global fashion retailer.

He is proficient in ASP.Net, MVC, C#, HTML, CSS, JavaScript, SQL Server TSQL.

Comments and Discussions

 
QuestionCode gone again Pin
Duncan Edwards Jones26-Aug-16 0:53
professionalDuncan Edwards Jones26-Aug-16 0:53 
AnswerRe: Code gone again Pin
dibley197326-Aug-16 1:49
dibley197326-Aug-16 1:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.