SDK投影到另一种类型

SDK投影到另一种类型

本文介绍了使用C#SDK投影到另一种类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用C#SDK查询MongoDB时,我希望能够投影为另一种类型.

I want to be able to project to another type when querying MongoDB using the C# SDK.

例如,下面我想使用构建器过滤器(或LINQ表达式)查询 MyType 的集合,但我想将结果投影到 MySubType.

For example, below I want to query the collection using builder filters (or LINQ expressions) for MyType, but I want to project the result to MySubType.

var mySubTypes = Database
    .GetCollection<MyType>("MyCollection")
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, documentId))
    .ProjectTo<MySubType>() // Project to another type??
    .ToList();

可以想象 MySubType MyType 的子集,使用继承表示:

One could imagine MySubType to be a subset of MyType, represented using inheritance:

public class MyType : MySubType
{
    [BsonElement("documents")]
    public List<string> Documents { get; set; }
}

public class MySubType
{
    [BsonElement("name")]
    public string Name { get; set; }
}

我为什么要这样做?

因为 Documents 数组非常大,并且仅在数据库引擎内的查询(即过滤)期间使用.检索和序列化此阵列将是不必要的费用.

Because the Documents array is very large and used purely during querying (i.e. to filter) within the database engine. Retrieving and serializing this array will be an unnecessary cost.

推荐答案

我已经找到了执行所需映射的方法:

I have found the way to execute mapping you want:

collection
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" }))
    .Project(Builders<MyType>.Projection.Exclude(c => c.Documents))
    .As<MySubType>()
    .ToList();

但是首先,您应该在忽略额外元素的情况下为您的SubType注册映射.我不明白它是100%,似乎是驱动程序的错误,它没有从mongo获取 Documents ,但知道 MyType 具有这种属性.请注意,您应该先注册类映射,然后再创建此类型的集合.

But first you should register mapping for your SubType with ignoring extra element. I don't understand it 100%, seems to be a bug of the driver, it doesn't get Documents from mongo, but knows, that MyType has such property. Note, you should register your class mapping, before you first create collection of this type.

if (!BsonClassMap.IsClassMapRegistered(typeof(MySubType)))
{
    BsonClassMap.RegisterClassMap<MySubType>(cm =>
    {
        cm.AutoMap();
        cm.SetIgnoreExtraElements(true);
    });
}

我是用示例数据完成的:

I did it with sample data :

var toInsert = new List<MyType>
{
    new MyType {Id = 1, Name = "bla", Documents =new List<string> {"a", "b", "v"}},
    new MyType {Id = 2, Name = "ada", Documents =new List<string> {"c", "d", "r"}},
};

并可以获得预期的输出:

And could get the expected output:

collection
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" }))
    .Project(Builders<MyType>.Projection.Exclude(c => c.Documents))
    .As<MySubType>()
    .ToList()
    .Dump();

这篇关于使用C#SDK投影到另一种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 05:07