如何使用C#和MongoDb获取自动增量可预测ID
我将MongoDb与.Net Core 3解决方案一起使用,这是我的问题。如何使用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有各种原因,我希望尽可能地坚持使用它。 我希望能够将一个对象插入到数据库中,并使用我可以通过编程猜测的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