views:

30

answers:

2

I'm writing some merge functionality in C# asp.NET MVC2. I am also using using Linq2SQL.

I have a block of code which calls two services, MessageService and UserService. These both in term call their appropriate repositories and make the amendments to the db. Each repository declares it's own instance of the repository so I'm thinking this will escalate the following code to DTC . The code is called from the AccountService, is this going to work at this level? And also is it bad practise to declare the DataContext at the top of every repository or should I pass the object around somehow? Thank you in advance

//Run the merge
try
{
    using (TransactionScope scope = new TransactionScope())
    {
        // Update Messages to be owned by primary user
        if (!_MessageService.UpdateCreatedById(MergeUser.UserID, CoreUser.UserID))
        {
            return false;
        }

        // Update Comments to be owned by primary user
        foreach (var curComment in _MessageService.GetUserComments(MergeUser.UserID))
        {
            curComment.CreatedBy = CoreUser.UserID;
        }

        _MessageService.Save();

        // Update Logins to be owned by primary user
        foreach (var CurLogin in _UserService.GetLogins(MergeUser.UserID))
        {
            CurLogin.UserID = CoreUser.UserID;
        }

        _UserService.Save();

        scope.Complete();
    }

    return true;
}
catch (Exception ex)
{
    _ErrorStack.Add(ex.Message);
    ErrorService.AddError(new ErrorModel("Portal", "WidgetRepository", ErrorHelper.ErrorTypes.Critical, ex));
    return false;
}
+1  A: 

Yes, This will work. TransactionScope leverages the Distributed transaction coordinator so it's capable of hosting Transactions beyond database levels.

Recommended practice for DataContext lifecycle is to restrict it to a unit-of-work.

this. __curious_geek
So i shouldnt pass the context between the services / repositories as mentioned by paddy?
Andi
TransactionScope does not know DataContext and it does not need to know DataContext. TransactionScope has been there even before DataContext.
this. __curious_geek
+1  A: 

I have two constructors on my repositories, one that takes a data context and one that does not (which then instatiates it's own). This means that I can create repositories using a shared data context as required.

My service classes then take a repository object in their constructor, so I can instantiate several services using repositories that are sharing a data context, if so required.

Paddy
How does your Update method work ?
this. __curious_geek
@this. __curious_geek - I tend to only use this technique for updates that span different areas of the system (as above). I call the updates on each of the services and then 'Save' on one of them which will submit the changes in my data context.
Paddy