Use predefined vs. custom enums to return appropriate message from service layer
I would not recommend using this pattern, personally. What you're effectively trying to do is signal error state, where 0 is null state and therefore success, similar to the way that you might do it with the Win32 API. The designers of c# and the .NET framework explicitly sought to avoid this pattern (and deem it to be an anti pattern). I think it works great for OS level work, and clearly does for both Windows and Linux, but it can be very cumbersome. 

The "c#" method of doing this is by using exceptions. For a method called SaveChanges, the return type is usually either void or bool. I personally recommend void, because bool doesn't give any context for what caused the operation to fail, and is really just a slim version using an enumeration. 

For the remainder of cases, there is USUALLY a built in exception type that is appropriate. InvalidOperationException can be used to state that you can't save the changes because the entity already exists, for instance. In a Web API, you can return something in one of the error ranges for this case.

If you really look at the exception model,  I believe you'll find that it does provide a decent solution to this problem for you. It liberates you from having to build complex enumerations, and mapping them across layers. Your application is then free to focus on interactions with the layer it communicates with, and you don't need to build extra services across each tier to describe what happened. Ideally, this means easier long term maintenance as well, because changing any part of the implementation does not result in needing to update the ENTIRE implementation.