使用C#SDK投影到其他类型

时间:2017-01-31 16:57:38

标签: c# .net mongodb mongodb-query mongodb-.net-driver

我希望能够在使用C#SDK查询MongoDB时投射到另一种类型。

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

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

可以想象MySubTypeMyType的子集,使用继承来表示:

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

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

为什么我要这样做?

因为Documents数组非常大并且在数据库引擎内查询(即过滤)时纯粹使用。检索和序列化此数组将是不必要的成本。

1 个答案:

答案 0 :(得分:1)

我找到了执行你想要的映射的方法:

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具有这样的属性。请注意,您应该首先注册您的类映射 ,然后再创建此类型的集合。

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

我用样本数据做了:

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"}},
};

可以获得预期的输出:

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

enter image description here