First, consider if you really need to synchronize based on an ID. Are you foreseeing a scale-up issue otherwise? As always, testing and benchmarking is your best option before seeking this possibly premature optimization.
That said, if the amount of entity IDs is not large, you could use this simple solution:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single, // required to hold the dictionary through calls
ConcurrencyMode = ConcurrencyMode.Multiple] // let WCF run all the calls concurrently
class Service
{
private readonly ConcurrentDictionary<int, object> _locks = new ConcurrentDictionary<int, object>();
public void MyWcfOperation(int entityId, other arguments)
{
lock (_locks.GetOrAdd(entityId, i => new Object())
{
// do stuff with entity with id = entityId
}
}
}
This does not deal with cleanup, so if you have a lot of entities, the dictionary would grow to contain a lock object for each one.