Versão curta:sim, use String em todos os lugares.
Se você estiver de acordo com as anotações, use:
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
Caso contrário, você pode usar um mapa de classe:
BsonClassMap.RegisterClassMap<i_YourModel>(cm =>
{
cm.AutoMap();
cm.SetIdMember(cm.GetMemberMap(x => x.Id)
.SetIdGenerator(StringObjectIdGenerator.Instance));
}
);
Versão longa :
É aconselhável usar algo opaco, que não esteja diretamente conectado à implementação do banco de dados subjacente, tanto quanto possível em seu modelo e camada de serviço (quando possível).
Anteriormente, os ids de chave primária eram geralmente grandes números, que eram então mapeados para uma coluna de chave primária numérica no banco de dados. No entanto, ao atribuir um novo id a uma nova entidade, era necessário fazer uma verificação no banco de dados para garantir um id exclusivo. Existem muitas técnicas, desde geradores de id LO-HI, colunas auto_increment, sequências etc.
Com o NoSQL, e a necessidade de mais paralelismo, a maioria das aplicações agora está usando UUIDs ou variações dele, pois o ID pode ser gerado com probabilidades razoáveis de ser único sem precisar perguntar ao banco de dados se ele é realmente único, ou usar sequências ou semelhantes, que são gargalos em um aplicativo que escala horizontalmente.
MongoDB não faz diferença, e usa ObjectId que são uma espécie de UUIDs.
Esses ids (tanto mongo quanto outros) sempre podem ser representados como Strings, geralmente uma representação HEX dos bytes que compõem a chave. Portanto, em seu modelo, use String como ids, em sua camada de serviço o mesmo, em sua camada de dados converta-o para qualquer formato que seja melhor para sua implementação de banco de dados subjacente, MongoDB neste caso.