【发布时间】:2017-03-03 18:08:34
【问题描述】:
我正在从旧的 MongoDB 驱动程序中移植一些代码以使用新的驱动程序,但遇到了问题。我有一个集合,其中包含来自公共基类的多个派生类型。以前,我能够使用派生类属性查询集合(使用基类型声明)并检索派生类文档。所以给定这些类:
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(Cat),typeof(Dog))]
class Animal
{
[BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
public string Id { get; set; }
public string Name { get; set; }
}
class Cat : Animal
{
public bool LikesFish { get; set; }
}
class Dog : Animal
{
public string FavouriteBone { get; set; }
}
然后我可以做类似的事情:
MongoCollection<Animal> animals = db.GetCollection<Animal>("Animals");
var q = Query<Cat>.EQ(c => c.LikesFish, true);
var catsThatLikeFish = animals.FindAs<Animal>(q).ToList();
效果很好。
但是现在我必须输入过滤器并且不能再编译:
IMongoCollection<Animal> animals = db.GetCollection<Animal>("Animals");
var query = Builders<Cat>.Filter.Eq(c => c.LikesFish, true);
var catsThatLikeFish = animals.FindSync(query);
并得到这个错误:
Error CS0411 The type arguments for method 'IMongoCollection<Animal>.FindSync<TProjection>(FilterDefinition<Animal>, FindOptions<Animal, TProjection>, CancellationToken)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
使用新驱动程序是否不再可能?我们有允许对这个集合进行通用查询的类,我现在看不到任何优雅的方法。
编辑:
可悲的是,单独的集合是行不通的,因为我们混合过滤器表达式以使用相同的查询拉回不同的类型。在上面的“猫和狗”示例中,如下所示:
var catQuery = Query<Cat>.EQ(c => c.LikesFish, true);
var dogQuery = Query<Dog>.EQ(c => c.FavouriteBone, "Beef");
var q = Query.Or(catQuery, dogQuery);
var catsThatLikeFishOrDogsThatLikeBeef = animals.FindAs<Animal>(q).ToList();
我会看看上面的“nameof”方法——它可能有效,但对我来说似乎缺乏旧方法的优雅......
非常感谢任何帮助!
谢谢,
史蒂夫
【问题讨论】:
-
除了下面 Maksim 的回答之外,在新的 API 中还有一个 OfType() 方法... IMongoCollection
dogs = db.GetCollection ("Animals").OfType ().
标签: c# .net mongodb mongodb-.net-driver