This project is read-only.

What's the right way to persist updates as part of a subdomain?

Sep 3, 2010 at 2:02 PM

I currently have a code snippet that essentially looks like this:

EmployeeCollection employees = EmployeeCollection.RunSelect(e => e.Department == "Information Technology");

foreach (Employee employee in employees)
{
	employee.Delete();
}

employees.Persist();

What's the right way to attach this delete (or any update in a similar format) to an existing subdomain? I'm aware of assigning a collection as follows:

EmployeeCollection employees = (EmployeeCollection)existingSubdomain[Collections.EmployeeCollection];

But I don't see how to make the two work together. Thanks in advance.

Sep 3, 2010 at 3:07 PM
Edited Sep 3, 2010 at 3:08 PM

You are doing it correctly, employees.Persist();.

When you create the employees collection a subdomain is created automatically to hold it.  You can't see it but if you call persist on the collection, the collection will handle the call to the subdomain that holds it.

Alternatively, you can create a Subdomain manually i.e. Subdomain s = new Subdomain(); and then add Collections and Commands to it.  This way the Subdomain will be visible.  To learn more I suggest you read this http://nhydrate.codeplex.com/wikipage?title=Subdomains%20Explained&referringTitle=Documentation.

By the way, I am not a member of the nHydrate team but have been using it over the last 6 months.

Cheers Rob.

Sep 3, 2010 at 3:10 PM
Edited Sep 3, 2010 at 3:11 PM

First I would suggest using the static bulk delete operation like so.

EmployeeCollection.DeleteData(e => e.Department == "Information Technology");

I know this is not what you want to do since you wish to add these deletes to a subdomain. I assume you want this to be persisted in a database transaction with other operations.

That said I think you need to add the EmployeeCollection to your other subdomain first. Then ensure you have the proper objects loaded and them call the individual delete methods.

So it would look something like this.


EmployeeCollection employeeCollection = existingSubdomain.GetCollection<EmployeeCollection>();
existingSubdomain.AddSelectCommand(new Acme.Northwind.Business.SelectCommands.EmployeeSelectAll());
existingSubdomain.RunSelectCommands();


Sep 3, 2010 at 3:18 PM

I am now sure exactly what you are trying to do. If you only want to delete data use the collection's static method "DeleteData". If you need an explicit subdomain because you are want to do many things in a database transaction (add customer, delete products, update widgets) that is a different story.

Sep 3, 2010 at 4:30 PM

Thanks for the comments. I'll try to clarify and give an example with a little more context. I understand that every operation done with a collection is inherently part of a subdomain, and I know about the static DeleteData and UpdateData methods. I'm not sure that using AddSelectCommand will work because the field I'm selecting on isn't a primary or foreign key, and I don't see how to add an arbitrary select command to a subdomain. Here's another example:

CategoryCollection categories = new CategoryCollection();

// Create a new category
Category category = categories.NewItem();
category.Name = "Fiction";
category.Persist();

// Move all the books with a certain author into the new category
BookCollection books = BookCollection.RunSelect(b => b.AuthorFirstName == "Terry" && b.AuthorLastName == "Pratchett");

foreach (Book book in books)
{
	book.CategoryID = category.ID;
}

books.Persist();

How do I ensure that the update to the BookCollection belongs to the same subdomain as the insert to CategoryCollection? I want them all to be part of the same transaction.

Sep 5, 2010 at 7:59 PM

I would do it a little differently. I would load the books and then add the category (because it is easier).

// Get all the books with a certain author into the new category
BookCollection books = BookCollection.RunSelect(b => b.AuthorFirstName == "Terry" && b.AuthorLastName == "Pratchett");

// Get category collection same subdomain
CategoryCollection categories = books.SubDomain.GetCollection<CategoryCollection>();
Category category = categories.NewItem();
category.Name = "Fiction";

// Move all books to new categoryforeach (Book book in books)
{
book.CategoryID = category.ID;
}

books.SubDomain.Persist();

 

Sep 7, 2010 at 1:52 PM

That makes sense. What would you do if in addition to a BookCollection, you also had an ArticleCollection and you were updating the category on both (assuming the update to the ArticleCollection would be exactly the same as the BookCollection: selecting by AuthorFirstName and AuthorLastName, and then updating the CategoryID)?

In the real world code code I'm working on, I have about 20-30 inserts, updates and deletes that I'm trying to group together in the same transaction: create or update an account, create or update one or more customers associated with the account, logically delete any existing customer addresses/phone numbers/email addresses (essentially update a DeleteDate column), insert or update associated customer addresses/phone numbers/email addresses, etc. In the previous data access layer we were using, we handled transactions with a TransactionScope.