Search code examples
asp.netentity-frameworkwcftransactionstransactionscope

WCF Transaction with multiple inserts


When creating a user, entries are required in multiple tables. I am trying to create a transaction that creates a new entry into one table and then pass the new entityid into the parent table and so on. The error I am getting is

The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)

I believe this is caused by creating multiple connections within a single TransactionScope, but I am unsure on what the best/most efficient way of doing this is.

    [OperationBehavior(TransactionScopeRequired = true)]
    public int CreateUser(CreateUserData createData)
    {

        // Create a new family group and get the ID
        var familyGroupId = createData.FamilyGroupId ?? CreateFamilyGroup();

        // Create the APUser and get the Id 
        var apUserId = CreateAPUser(createData.UserId, familyGroupId);

        // Create the institution user and get the Id
        var institutionUserId = CreateInsUser(apUserId, createData.AlternateId, createData.InstitutionId);

        // Create the investigator group user and return the Id
        return AddUserToGroup(createData.InvestigatorGroupId, institutionUserId);

    }

This is an example of one of the function calls, all the other ones follow the same format

    public int CreateFamilyGroup(string familyGroupName)
    {
        var familyRepo = _FamilyRepo ?? new FamilyGroupRepository();
        var familyGroup = new FamilyGroup() {CreationDate = DateTime.Now};

        return familyRepo.AddFamilyGroup(familyGroup);

    }

And the repository call for this is as follows

public int AddFamilyGroup(FamilyGroup familyGroup)
        {
            using (var context = new GameDbContext())
            {
                var newGroup = context.FamilyGroups.Add(familyGroup);
                context.SaveChanges();
                return newGroup.FamilyGroupId;
            }
        }

Solution

  • I believe this is caused by creating multiple connections within a single TransactionScope

    Yes, that is the problem. It does not really matter how you avoid that as long you avoid it. A common thing to do is to have one connection and one EF context per WCF request. You need to find a way to pass that EF context along.

    The method AddFamilyGroup illustrates a common anti-pattern with EF: You are using EF as a CRUD facility. It's supposed to me more like a live object graph connected to the database. The entire WCF request should share the same EF context. If you move in that direction the problem goes away.