如何使用BsonClassMap将POCO域对象属性映射为手动或DBRef引用?

Geo*_*off 5 c# mongodb mongodb-.net-driver

使用BsonClassMap,是否可以映射域对象引用,同时保持域对象程序集持久无知(将public A Reference { get; set; }属性更改为下面public MongoDBRef Reference{ get; set; }的示例类B是不可接受的).

对于这种情况,引用的对象不是同一聚合的一部分,不应存储为嵌套文档.

是否可以在这样的关系中映射两个域对象:

public class A
{
    public Guid Id {get; private set; }
}

public class B
{
    public Guid Id { get; private set; }
    public A Reference { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

进入以下文档结构:

// Collection for class A
{ _id: "11111111-1111-1111-1111-111111111111" }

// Collection class B
{ 
    _id: "22222222-2222-2222-2222-222222222222",
    reference_id: "11111111-1111-1111-1111-111111111111"
}
Run Code Online (Sandbox Code Playgroud)

映射可能如下所示:

BsonClassMap.RegisterClassMap<A>(cm => 
{
    cm.MapIdProperty(c => c.Id)
        .SetIdGenerator(new GuidGenerator())
        .SetRepresentation(BsonType.String);
}

BsonClassMap.RegisterClassMap<B>(cm => 
{
    cm.MapIdProperty(c => c.Id)
        .SetIdGenerator(new GuidGenerator())
        .SetRepresentation(BsonType.String);

    // How do I map the B.Reference to a manual reference (like 
    // the sample doc structure above) or possibly as a DBRef?
}
Run Code Online (Sandbox Code Playgroud)

因此,在不更改模型的情况下,如何将Reference属性映射到对象A,从对象映射B为DBRef或手动引用(如上面的示例文档结构中所示)?

这可能使用BsonClassMap吗?或者为了使用BsonClassMap并保持我的域程序集持久无知,我是否需要将模型更改为:

public class A
{
    public Guid Id {get; private set; }
}

public class B
{
    public Guid Id { get; private set; }
    public Guid ReferenceId { get; set; } // Don't reference the object directly,
                                          // just store the Guid to the 
                                          // referenced object.
}
Run Code Online (Sandbox Code Playgroud)

Geo*_*off 3

我向 mongodb-csharp 用户组提出了同样的问题,并得到了 craiggwilson 的回复:

您需要将 ReferenceProperty 更改为 ReferencePropertyId。我们不支持引用文档的延迟加载(或急切加载)。

由于 A 不是 B 的聚合,因此用这些术语进行讨论时实际上更有意义。通常,不需要加载被引用聚合(B)来处理引用聚合(A)。可能您确实需要来自 B 的一些信息。在这种情况下,请考虑稍微反规范化并创建一个聚合为 A 的真实实体 (BSummary)。如果某些摘要信息不可变或不经常更改,则这是有意义的。