Entity Activities

This topic applies to Windows Workflow Foundation 4 (WF4).

This sample shows how to use the ADO.NET Entity Framework with Windows Workflow Foundation to simplify data access.

The ADO.NET Entity Framework enables developers to work with data in the form of domain-specific objects, properties and relationships such as Customers, Orders, Order Details and the relationships between these entities. The ADO.NET Entity Framework does this by providing a level of abstraction that enables programming against a conceptual application model instead of programming directly against a relational storage schema. For more information about the ADO.NET Entity Framework see ADO.NET Entity Framework.

Sample details

This sample uses the Northwind database and includes scripts for creating and removing the Northwind database (Setup.cmd and Cleanup.cmd). The projects in this sample include an Entity Data Model based on the Northwind database. You can find the model by opening the Northwind.edmx file that is included in the project. This is the model that defines the shape of the objects that can be accessed using the ADO.NET Entity Framework.

The following activities are included in this sample:

  • EntitySQLQuery: The EntitySQLQuery activity allows you to retrieve objects from the database based on an Entity SQL query string. Entity SQL is a store independent language that is similar to SQL and it allows you to specify queries based on the conceptual model and the entities that are a part of the model or domain. For more information about Entity SQL Language, see Entity SQL Language.

  • EntityLinqQuery: This activity allows you to retrieve objects from the database based on a LINQ query or predicate.

  • EntityAdd: The EntityAdd activity allows you to add an entity or a collection of entities to the database.

  • EntityDelete: The EntityDelete activity allows you to delete an entity or a collection of entities from the database.

  • ObjectContextScope: The previously mentioned activities can only be used within a containing ObjectContextScope activity instance. The ObjectContextScope activity sets up the connection to the database. It requires a connection string (that is either passed in or retrieved using a configuration file setting). The ObjectContextScope activity makes it easy to perform a group of related operations on entities. Because this scope maintains an active connection, it is a No Persist scope. In addition, when the ObjectContextScope activity exits, any changes that are made to objects retrieved using Entity Activities within that scope automatically get persisted back to the database, and no explicit or subsequent action is required to save objects back to the database.

Using the entity activities

The following code snippets demonstrate how to use the entity activities presented in this sample.

EntitySql

The code snippet below shows how to query all customers in London sorted by name and how to iterate through the list of customers.

Variable<IEnumerable<Customer>> londonCustomers = new Variable<IEnumerable<Customer>>();
DelegateInArgument<Customer> iterationVariable = new DelegateInArgument<Customer>();

// create and return the workflow
return new ObjectContextScope
{
    ConnectionString = new InArgument<string>(connStr),
    ContainerName = "NorthwindEntities",
    Variables = { londonCustomers },
    Body = new Sequence
        {
            Activities = 
                {             
                    new WriteLine { Text = "Executing query" },                          
                    // query for all customers that are in london 
                    new EntitySqlQuery<Customer>
                    {
                        EntitySql =  @"SELECT VALUE Customer 
                                        FROM NorthwindEntities.Customers AS Customer 
                                        WHERE Customer.City = 'London' 
                                        ORDER BY Customer.ContactName",
                        Result = londonCustomers
                    },

                    // iterate through the list of customers and display them 
                    new ForEach<Customer>
                    {                                    
                        Values = londonCustomers,
                        Body = new ActivityAction<Customer>
                        {
                            Argument = iterationVariable,
                            Handler = new WriteLine 
                            { 
                                  Text = new InArgument<String>(e =>  
                                              iterationVariable.Get(e).ContactName) 
                            }
                        }
                    }
                }
        }               
};   

EntityLinqQuery

The code snippet below shows how to query all customers in London and how to iterate through the resulting list of customers.

Variable<IEnumerable<Customer>> londonCustomers = new Variable<IEnumerable<Customer>>() { Name = "LondonCustomers" };
DelegateInArgument<Customer> iterationVariable = new DelegateInArgument<Customer>() { Name = "iterationVariable" };

return new ObjectContextScope
{
    ConnectionString = new InArgument<string>(connStr),
    ContainerName = "NorthwindEntities",
    Variables = { londonCustomers },
    Body = new Sequence
    {
        Activities = 
        {             
            // return all the customers that match with the provided Linq predicate
            new EntityLinqQuery<Customer>
            { 
                Predicate = new LambdaValue<Func<Customer, bool>>(
                          ctx => new Func<Customer, bool>(c => c.City.Equals("London"))),                            
                Result = londonCustomers
            },

            // iterate through the list of customers and display in the console
            new ForEach<Customer>
            {                                    
                Values = londonCustomers,
                Body = new ActivityAction<Customer>
                {
                    Argument = iterationVariable,
                    Handler = new WriteLine 
                    { 
                        Text = new InArgument<String>(e => 
                                      iterationVariable.Get(e).ContactName) 
                    }
                }
            }
        }
    }
};

EntityAdd

The code snippet below shows how to add an OrderDetail record to an existing Order.

Variable<IEnumerable<Order>> orders = new Variable<IEnumerable<Order>>();
Variable<IEnumerable<OrderDetail>> orderDetails = new Variable<IEnumerable<OrderDetail>>();
Variable<Order> order = new Variable<Order>();
Variable<OrderDetail> orderDetail = new Variable<OrderDetail>();            

return new ObjectContextScope
{
    Variables = { order, orders, orderDetail, orderDetails },
    ContainerName = "NorthwindEntities",
    ConnectionString = new InArgument<string>(connStr),                
    Body = new Sequence
    {                    
        Activities = 
        {                          
           // get the order where we want to add the detail
           new EntitySqlQuery<Order>
           {
               EntitySql =  
                    @"SELECT VALUE [Order]
                      FROM NorthwindEntities.Orders as [Order]
                      WHERE Order.OrderID == 10249",
               Result = orders
           },

           // store the order in a variable
           new Assign<Order> 
           {
               To = new OutArgument<Order>(order),
               Value = new InArgument<Order>(c => orders.Get(c).First<Order>())
           },
           
           // add the detail to the order
           new EntityAdd<OrderDetail>
           {
               Entity = new InArgument<OrderDetail>(c => 
                                         new OrderDetail { 
                                                  OrderID=10249, ProductID=11, 
                                                  Quantity=1, UnitPrice = 15, 
                                                  Discount = 0, Order = order.Get(c) })
           }
        }
    }
};

EntityDelete

The code snippet below shows how to delete an existing OrderDetail record in an Order (if it exists).

Variable<IEnumerable<OrderDetail>> orderDetails = new Variable<IEnumerable<OrderDetail>>();            

return new ObjectContextScope
{
    Variables = { orderDetails },
    ConnectionString = new InArgument<string>(connStr),
    ContainerName = "NorthwindEntities",
    Body = new Sequence
    {
        Activities = 
        {             
            // find the entitiy to be deleted (order detail for product 11 in order 10249)
            new EntitySqlQuery<OrderDetail>
            {
                EntitySql = @"SELECT VALUE OrderDetail
                                FROM NorthwindEntities.OrderDetails as OrderDetail
                               WHERE OrderDetail.OrderID == 10249 
                                 AND OrderDetail.ProductID == 11",
                Result = orderDetails
            },

            // if the order detail is found, delete it, otherwise, display a message
            new If
            {
                Condition = new InArgument<bool>(c=>orderDetails.Get(c).Count() > 0),
                Then = new Sequence
                { 
                    Activities = 
                    {                                    
                        new EntityDelete<OrderDetail>
                        {
                            Entity = new InArgument<OrderDetail>(c => 
                                              orderDetails.Get(c).First<OrderDetail>())
                        },
                    }
                },                            
                Else = new WriteLine { Text = "Order Detail for Deleting not found" }                            
            }                                                
        }
    }
};

To use this sample

You must create the Northwind database in your local SQL server Express instance before running this sample.

To set up the Northwind database

  1. Open a command prompt.

  2. In the new command prompt window, navigate to the EntityActivities\CS folder.

  3. Type setup.cmd and press ENTER.

To run the sample

  1. Using Visual Studio 2010, open the EntityActivities.sln solution file.

  2. To build the solution, press CTRL+SHIFT+B.

  3. To run the solution, press CTRL+F5.

After running this sample, you may want to remove the Northwind database.

To uninstall the Northwind database

  1. Open a command prompt.

  2. In the new command prompt window, navigate to the EntityActivities\CS folder.

  3. Type cleanup.cmd and press ENTER.

Ee622984.Important(en-us,VS.100).gif Note:
The samples may already be installed on your computer. Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WF samples. This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\EntityActivities