[英]MongoDB ObjectIds exposure
我有一個數據層(包含與MongoDB的連接),一個域層(包含repos和實體)和一個服務層(包含服務和模型)
現在因為我的實體使用ObjectIds,它們需要MongoDB的知識(這很好嗎?)
我的服務調用返回這些實體的存儲庫,然后將它們轉換為模型。 由於實體上的ObjectId屬性,這導致我的服務層需要MongoDB的知識。
有沒有辦法可以避免這種情況? 我聽說我可以使用我的Id作為類型字符串,當存儲數據時,MongoDB會將其轉換為ObjectId嗎?
簡短版本:是的,到處使用String。
如果您對注釋沒問題,請使用:
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
否則你可以使用類映射:
BsonClassMap.RegisterClassMap<i_YourModel>(cm =>
{
cm.AutoMap();
cm.SetIdMember(cm.GetMemberMap(x => x.Id)
.SetIdGenerator(StringObjectIdGenerator.Instance));
}
);
長版:
建議盡可能在模型和服務層中使用不透明的東西(不直接連接到底層數據庫實現)(如果可能)。
以前,主鍵ID通常是大數字,然后映射到數據庫上的數字主鍵列。 但是,在為新實體分配新ID時,必須對數據庫進行檢查以確保具有唯一ID。 存在許多技術,從LO-HI id生成器到auto_increment列,到序列等。
對於NoSQL,以及對更多並行性的需求,大多數應用程序現在使用UUID或其變體,因為ID可以以合理的概率生成,它將是唯一的,而不必詢問數據庫它是否真的是唯一的,或者使用序列或類似,這是水平擴展的應用程序中的瓶頸。
MongoDB沒有區別,並使用ObjectId作為一種UUID。
這些ID(包括mongo和其他)總是可以表示為字符串,通常是組成鍵的字節的HEX表示。 因此,在您的模型中使用String作為ID,在您的服務層中相同,在您的數據層中將其轉換為更適合您的底層數據庫實現的任何格式,在本例中為MongoDB。
有時僅映射Id可能會令人困惑,以及在同一實體中可能有另一個objectId(可能是引用)的情況下會發生什么?
您可以使用配置模式上的映射約定為objectId創建映射。 看看下面的實現:
public static class MongoDbConventionRegistry
{
public static void Register()
{
var conventionPack = new ConventionPack {new StringObjectIdMemberMapConvention()};
ConventionRegistry.Register("CustomConventions", conventionPack, t => t.FullName.StartsWith("YourNamespace.Model.Entities.etc"));
}
}
public class StringObjectIdMemberMapConvention : IMemberMapConvention
{
private readonly Regex _memberMatchRegex = new Regex(@"(^Id$)|(.+ObjectId?$)",RegexOptions.Compiled); // you can change this regex to match the convention you want
public string Name {
get { return "StringObjectId"; }
}
public void Apply(BsonMemberMap memberMap)
{
if (memberMap == null)
return;
if(memberMap.MemberType == typeof(string) && _memberMatchRegex.IsMatch(memberMap.ElementName) )
memberMap.SetRepresentation(BsonType.ObjectId);
}
}
因此,對於這種情況,任何以objectId結尾的Id和任何其他屬性都將映射到objectId,因此您可以將實體ID保留為字符串,驅動程序將為您處理轉換,當您不想攜帶時更方便系統中大多數圖層之間的mongodb依賴關系。
您可以將約定更改為您想要的任何內容,我只想高亮顯示該功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.