DMur
DMur

Reputation: 659

c# pass DB Context object to second function

I am trying to refactor a switch statement so I am not repeating code in each case.

This is a simplified example of the first two cases in my current switch statement. Note the db context objects in case.1 and case.2 userActions.Action1 and userActions.Action2:

public void UserClick(int actionNumber, string pageType, string userId, string userEmail)
{
var userActions = _context.RGWActions.Find(userId);
        
switch (actionNumber)
{
     case 1:
          userActions.Action1++;
          userActions.UserTotal++;
     break;
     case 2:
          userActions.Action2++;
          userActions.UserTotal++;
     break;
_context.SaveChanges();
}

I want to replace the code in case.1 and case.2 two with something like the below, so that I only have one function call in each:

switch (actionNumber)
{
     case 1:
          incrementUserAction(userId, userActions.Action1, "Action1");
     break;
     case 2:
          incrementUserAction(userId, userActions.Action2, "Action2");
     break;
}

For my incrementUserAction function below, I am passing in the userId and currentValue with no problem. But I can't figure out how to pass in an actionType parameter or object or something similar to reference the correct object; userActions.Action1 or userActions.Action2 from the cases above.

private void incrementUserAction(string userId, int currentValue, string actionType)
{
    var userActions = _context.RGWActions.Find(userId);

    userActions.(actionType) = currentValue++;
    userActions.UserTotal++;
    _context.SaveChanges();
}

In the above example I have tried to just pass a string to represent the column name "Action1" or "Action2". I have also tried variations of userActions.actionType and object actionType etc.

Upvotes: 0

Views: 30

Answers (1)

Paul Wheeler
Paul Wheeler

Reputation: 20170

C# objects don't provide easy access to properties by name, so while you could use reflection to read and update property values by the specified name, you should generally avoid that for performance and type safety reasons. A better approach here would be to have your incrementUserAction method take a lambda that performs the different types of updates:

private void incrementUserActions(string userId, Action<RGWActions> update)
{
    var userActions = _context.RGWActions.Find(userId);

    update(userActions);
    userActions.UserTotal++;
    _context.SaveChanges();
}

And the code that calls this function would look like this:

switch (actionNumber)
{
     case 1:
          incrementUserAction(userId, userActions => { userActions.Action1++; });
     break;
     case 2:
          incrementUserAction(userId, userActions => { userActions.Action2++; });
     break;
}

Upvotes: 1

Related Questions