source

.NET Guid를 MongoDB 개체로 변환아이디

manysource 2023. 6. 29. 20:14

.NET Guid를 MongoDB 개체로 변환아이디

.NET GUID를 MongoDB 개체로 변환하는 방법ID(C# 단위).또한 객체에서 동일한 GUID로 다시 변환할 수 있습니까?신분증?

변환할 수 없습니다.ObjectId안으로GUID두 가지 다른 것(다른 크기, 알고리즘)이기 때문에 그 반대도 마찬가지입니다.

mongoDb에 대해 모든 유형을 사용할 수 있습니다._id포함하여GUID.

예를 들어 공식 c# 드라이버에서는 속성을 지정해야 합니다.[BsonId]:

[BsonId]
public Guid Id {get;set;}

[BsonId]
public int Id {get;set;}

개체 ID:

BSON 객체ID는 4바이트 타임스탬프(에포크 이후 초), 3바이트 시스템 ID, 2바이트 프로세스 ID 및 3바이트 카운터로 구성된 12바이트 값입니다.타임스탬프 및 카운터 필드는 다른 BSON과 달리 빅 엔디안으로 저장해야 합니다.이것은 그것들이 바이트별로 비교되고 우리는 대부분 증가하는 순서를 보장하기를 원하기 때문입니다.

GUID:

GUID의 값은 {21}과 같이 32자의 16진수 문자열로 표시됩니다.EC2020-3AEA-1069-A2DD-08002B30309D}은(는) 일반적으로 128비트 정수로 저장됩니다.

참고로 ObjectId에서 Guid로 변환할 수 있습니다.

    public static Guid AsGuid(this ObjectId oid)
    {
        var bytes = oid.ToByteArray().Concat(new byte[] { 5, 5, 5, 5 }).ToArray();
        Guid gid = new Guid(bytes);
        return gid;
    }

    /// <summary>
    /// Only Use to convert a Guid that was once an ObjectId
    /// </summary>
    public static ObjectId AsObjectId(this Guid gid)
    {
        var bytes = gid.ToByteArray().Take(12).ToArray();
        var oid = new ObjectId(bytes);
        return oid;
    }

직접적인 대답은 아니지만 _id be an Object라는 요구 사항은 없습니다.고유한 ID입니다.

유효한 유형은 _I would include object or a. 당신은 _id에 대한 GUID를 사용하여 (단일성 위반을 제외하고) 괜찮을 것입니다. 사실 ObjectID는 사용자 지정 GUID에 불과합니다.

모든 것을 처음부터 시작하는 경우 "Id" 구성원을 입력할 수 있습니다.Guid대신에ObjectId모델이 참조할 필요가 없기 때문에 이 방법이 선호됩니다.MongoDB.Bson거의 틀림없이 더 이상 POCO 클래스가 아닙니다.당신은 심지어 필요하지도 않습니다.[BsonId]회원의 이름을 "Id"로 지정하면 속성을 부여하며, 위의 이유로 그렇게 하지 않는 것이 좋습니다.

이미 사용 중인 경우ObjectIdPOCO 클래스에서 "Id"(클래스에서)의 유형을 변경하고 싶지만 "_id"(데이터에서)의 유형을 변경할 수 없는 경우 사용자 지정 직렬화기를 만들 수 있습니다.

public class SafeObjectIdSerializer: ObjectIdSerializer
{
    public SafeObjectIdSerializer() : base() { }

    public override ObjectId Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var bsonReader = context.Reader;

        var bsonType = bsonReader.GetCurrentBsonType();

        switch (bsonType)
        {
            case BsonType.Binary: {

                var value = bsonReader
                        .ReadBinaryData()
                        .AsGuid
                        .ToString()
                        .Replace("-", "")
                        .Substring(0, 24);

                return new ObjectId(value);
            }
        }

        return base.Deserialize(context, args);
    }
}

애즈 미들토미가 언급한 것은, 다음과 같습니다.Guid로.ObjectId손실이 발생하지만 해당 필드를 사용하는 방법에 따라 문제가 없을 수 있습니다.위에서는 처음 24개의 16진수 문자를 사용하고 나머지 8개는 삭제합니다.임의로 저장하는 경우ObjectId값이 "int", "int", "objectId", "int"와 같은 값입니다.

도 쓰도시면려를 쓰기 .ObjectId~하듯이Guid당신이 의존하는 한 "_id" 유형을 혼합하는 것은 아무 것도 해롭지 않은 것 같습니다.base.Deserialize()하지만 제가 틀릴 수도 있고 당신의 구현에 따라 문제가 될 수도 있습니다.그 문서에는 어느 쪽이든 언급되어 있지 않습니다.이를 위해 위 클래스에 이 재정의를 추가할 수 있습니다.

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, ObjectId value)
    {
        var bsonWriter = context.Writer;
        var guidString = value
            .ToString()
            .Insert(8, "-")
            .Insert(13, "-")
            .Insert(18, "-")
            .Insert(23, "-") + "00000000";
        var asGuid = new Guid(guidString);
        bsonWriter.WriteBinaryData(new BsonBinaryData(asGuid));
    }

글로벌 역직렬화기로 만들려면:

public class CustomSerializationProvider : IBsonSerializationProvider
{
    public IBsonSerializer GetSerializer(Type type)
    {
        if (type == typeof(ObjectId))
        {
            return new SafeObjectIdSerializer();
        }

        //add other custom serializer mappings here

        //to fall back on the default:
        return null;
    }
}

그러면 당신의 Global.asax처럼 한 번만 부를 수 있는 곳.Application_Start()

BsonSerializer.RegisterSerializationProvider(new CustomSerializationProvider());

언급URL : https://stackoverflow.com/questions/5514111/convert-net-guid-to-mongodb-objectid