Updating complex objects
I was looking at what you had coded here


var deleteRemovedSubcategories = @"
    DELETE FROM dbo.Subcategories 
    WHERE CategoryId = @Id 
        AND Id NOT IN @Ids";



and it took me a minute to figure out exactly what the Where clause was filtering, what finally gave it away was the name of the C# variable deleteRemovedSubcategories. If it were possible I would change some of these column names and/or T-SQL variables so that it is more clear what you are saying here.