throw ex resets the stack trace while throw doesn’t.
When we use “throw” , it will throw a new exception without carrying real error info. But when we use “throw ex”, object ex will have error info like ErrorMessage from which we can identity the real reason behind this exception.Another scenario, if we wish to show user-friendly error message for technical exception (like Database connect issue), we can change ErroMessage property to a user-friendly message and throw that exception as “throw ex” to client.
throw gives original error stack information.throw ex gives stack trace of exception will be replaced with a stack trace starting at the re-throw point. Prefer to use "throw" instead of "throw ex" because it will give accurate error stack information
https://www.c-sharpcorner.com/blogs/difference-between-throw-and-throw-ex-in-c-sharp1