2014-09-19 68 views
3

我有一个数据层(包含连接的MongoDB),领域层(含回购和实体)和服务层(包含服务和模型)MongoDB中的ObjectID曝光

,因为现在我的实体使用的ObjectID,他们需要MongoDB的知识(这很好吗?)

我的服务获取调用返回这些实体的存储库,然后将它们转换为模型。由于实体上的ObjectId属性,这导致我的服务层需要了解MongoDB。

有没有办法避免这种情况?我听说我可以使用我的ID作为类型字符串,当存储数据时,MongoDB会将其转换为ObjectId?

回答

1

有时仅映射Id可能会引起混淆,并且如果在同一个实体中可能有另一个objectId(也许是引用),会发生什么情况?

那么你可以使用地图convention over configuration模式制作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结束将被映射到OBJECTID任何其他财产,这样你就可以留下您的实体ID作为字符串和驱动程序将处理转换你,当你不想在系统中的大多数层之间携带mongodb依赖时更方便。

您可以将约定更改为任何您想要的,我只是想要突出该功能。

3

简版:是的,无处不在。

如果您没有问题的注释,然后使用:

[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。

+0

所以我的UserModel将有字符串UserId和我的UserEntity也将有字符串UserId?或者仍然需要MongoDb的知识,并在实体 – Luke 2014-09-19 15:10:11

+0

上使用ObjectId试图澄清答案。 – 2014-09-19 15:19:00