如何使用C#和MongoDb获取自动增量可预测ID

如何使用C#和MongoDb获取自动增量可预测ID,c#,.net,mongodb,C#,.net,Mongodb,我将MongoDb与.Net Core 3解决方案一起使用,这是我的问题。 我选择MongoDb有各种原因,我希望尽可能地坚持使用它。 我希望能够将一个对象插入到数据库中,并使用我可以通过编程猜测的id检索它。 我的目标是: public class myclass { public int Id {get; set;} public string SomeValue {get; set;} } 但是这样做只会插入默认值int,就是这样。我事先不知道id,这就是为什么我基本

我将MongoDb与.Net Core 3解决方案一起使用,这是我的问题。
我选择MongoDb有各种原因,我希望尽可能地坚持使用它。 我希望能够将一个对象插入到数据库中,并使用我可以通过编程猜测的id检索它。 我的目标是:

public class myclass
{
    public int Id {get; set;}

    public string SomeValue {get; set;} 
}
但是这样做只会插入默认值
int
,就是这样。我事先不知道id,这就是为什么我基本上想要自动递增。 我还尝试向我们介绍了以下格式:

public class myclass
{
    [BsonId]
    public ObjectId Id {get; set;}

    public string SomeValue {get; set;} 
}
即使它能自动递增,它也能以mongo方式递增。
ObjectId(“5e68f3b3407d9b261b5312fc”)
以这种方式不太可预测。
其中包含以下内容:
这非常方便,所以我尝试使用
Increment
,但在检索时无法使其工作

var doc = await _collection.FindAsync(x => x.ID.Increment == myId).ConfigureAwait(false);
或者像这样:

var doc = await _collection.FindAsync(new FilterDefinitionBuilder<Question>().Gt(x => x.ID.Increment, myId)).ConfigureAwait(false);
var doc=await\u collection.FindAsync(new FilterDefinitionBuilder().Gt(x=>x.ID.Increment,myId)).ConfigureAwait(false);
这种方法处理
int
ID,就像我试图获取
ID==0


问题是,有没有更好或更合适的方法让autoincrement
int
或使用C#和mongoDb的任何可预测值?

创建一个序列表,其中包含唯一ID的名称列表和当前唯一ID的编号(如果您认为将建立超过20亿条记录,则长度可能相同)并编写一个存储过程,该过程将安全地返回所提供名称的下一个值,并在一个事务中将当前数字递增一。然后,每当您需要将某些内容保存到数据库时,获取一个唯一的id,将其压缩(转换为base64、32,无论什么),并将其用作行id

这种方法的优点是,一旦您编写了它,您就可以将它用于您想要的任何其他id标记。我们使用类似的表为客户、联系人、活动、操作等生成不同的ID

这是我们用来获取唯一编号的代码

    ''' <summary>
    ''' Returns the next unique number for the supplied id in the system,
    ''' automatically refreshes when the numbers run out
    ''' </summary>
    ''' <param name="name">The name of the unique number to return</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetUniqueNumber(ByVal name As String) As Integer
        Dim sequentialRow As MSLDataModel.sequentialRow
        AcquireWriterLock("GetUniqueNumber")
        Try
            'Get the squential row for this name first and check that it exists
            sequentialRow = CachedData.sequential.FindByid(name)
            If sequentialRow Is Nothing Then
                CachedData.AcceptChanges()
                sequentialRow = CachedData.sequential.AddsequentialRow(name, name, 1, 1, Integer.MaxValue, 10, 1)
                databaseConnection.SaveDataTable(CachedData.sequential)
            End If

            Dim number As Integer
            Dim range As Integer
            'if we have run out of numbers then read more numbers from the database
            If sequentialRow.range < 1 Then
                Dim retry As Integer = 0
                While (Not ReadUniqueNumber(sequentialRow) And retry < 10)
                    retry = +1
                End While
            End If
            'get the current number and reduce the available numbers by 1
            number = sequentialRow.number
            range = sequentialRow.range
            sequentialRow.range = range - 1
            sequentialRow.number = number + 1
            Return number
        Finally
            ReleaseWriterLock()
        End Try
    End Function

    Private Function ReadUniqueNumber(ByVal sequentialRow As MSLDataModel.sequentialRow) As Boolean
        Try
            Dim col As Dictionary(Of String, Object)
            Dim res As DataSet
            col = New Dictionary(Of String, Object)
            col.Add("@id", sequentialRow.id)
            res = databaseConnection.RunStoredProcedure("seq_update", col)
            If res.Tables(0).Rows.Count > 0 Then
                Dim row As DataRow
                row = res.Tables(0).Rows(0)
                sequentialRow.number = row.Item("number")
                sequentialRow.range = row.Item("range")
            End If
        Catch ex As Exception
            MSLODBCAbstractionLayer.Logger.LogException(ex)
            Return False
        End Try
        Return True
    End Function

这种方法是否存在巨大的性能缺陷?如果您有一个代码示例,我将非常感谢。我们有两个存储过程,一个返回单个数字,另一个返回比当前数字高x的数字。在我们的CRM/预订系统中,新行是由用户输入创建的,因此我们只使用单号过程,但在批处理应用程序中,我们使用多号过程。我无法提供存储过程,因为它是Sybase/MS Sql特定的,所以您需要自己解决如何执行事务锁定。

    Public Function GetUniqueNumber(ByVal uniqueName As String) As Integer Implements MediaSystems.InterfaceDefinitions.IMSLDataAbstractionLayer.GetUniqueNumber
        Logger.StartFunction()
        Try
            'Check to see if this action can be performed

            'get the unique number from the cache
            Return Cache.GetUniqueNumber(uniqueName)
        Finally
            Logger.EndFunction()
        End Try
    End Function