Looking at posts such as this on StackOverflow, the consensus seems to be that you should hide incrementing ID's from external API's for security.However, I'm having trouble working out a good implementation.I don't want to use Guids as the ID, because as stated here, it leads to page fragmentationand when I did it before, the DB had performance issues (in part due to the Id's).I came up with the following class structure. It has an int ID, then a Guid for external identification. The problem with this is that is now means there are excessive calls to the db for inserts and updates.Models:public class Blog{    public int BlogId { get; set; }    public Guid BlogGuid { get; set; } = Guid.NewGuid();    public string Url { get; set; }    public List<Post> Posts { get; set; }}public class Post{    public int PostId { get; set; }    public Guid PostGuid { get; set; }    public string Title { get; set; }    public string Content { get; set; }    public int BlogId { get; set; }    public Blog Blog { get; set; }}DTO:    public class BlogDto{    // No int id on dto    public string Url { get; set; }    public Guid BlogGuid { get; set; }    public List<PostDto> Posts { get; set; }}public class PostDto{    // No int id on dto    public Guid PostGuid { get; set; }      public string Title { get; set; }    public string Content { get; set; }    public BlogDto Blog { get; set; }}Getting the data is fine. As before, we just get and convert to the DTO.When wanting to do an update or insert, the data comes back with just the Guid id's on all objects. I can't just send entities back, as they do in the tutorials such as this.I now need to get the original data (by Guid, with includes), then I need to get the related data (by Guid) and work out what to do (something could have been inserted, deleted, or just altered). It all feels a bit messy and unnecessarily chatty with the database.Is this just a case of more secure = slower, or is this design (as I suspect) somehow inefficient?
How to avoid incrementing ID's being exposed in an API?
c#;database design;entity framework
The advice at the post you linked about using GUIDs for clustered primary keys is seven years old and almost certainly bad advice today.  The article it refers to references SQL Server 7.We use GUIDs for every primary key in our database, and expose those GUIDs in the URLs that hit our JSON services.  We can do this because we don't expose our database internals to the outside world; absent this information, you might as well be exposing random numbers.  We don't have any of the performance problems that are predicted in that post.GUIDs have some unique properties that make them very useful as primary and foreign keys.  Because they are globally unique, you can use a single JOIN without worrying about which table you are joining to.  Unlike sequential ID's, guessing a neighboring GUID is very nearly impossible, for the same reasons that make GUIDs ideal identifiers in the first place.The ideal way to prevent exposing incremental ID's?  Use GUIDs as primary keys instead.  While GUIDs are not a magic security feature, neither is obfuscating ints.  Make sure the rest of your security (SSL, logins, role-based security, hardening from X-site request forgeries, etc. etc.) is solid first, and exposing GUIDs to represent what they're designed to represent anyway (i.e. unique resources) will be the least of your problems.