为什么 AsQueryable 不意味着对_t鉴别器进行过滤
本文关键字:鉴别 过滤 AsQueryable 意味着 为什么 | 更新日期: 2023-09-27 18:32:11
假设模型
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof (Dog), typeof (Cat))]
class Animal
{
public ObjectId Id {get;set;}
public string Name {get;set;}
}
class Dog : Animal { public int BarkVolume {get;set;} }
class Cat : Animal { public int PurrVolume {get;set;} }
我可以执行以下操作:
var collection = new MongoClient().GetServer().GetDatabase("test").GetCollection<Animal("Animals");
collection.Save( new Dog { Name="spot", BarkVolume=7 } );
collection.Save( new Cat { Name="kitty", PurrVolume=2 } );
但是,如果我然后尝试只查询
猫var cats = collection.AsQueryable<Cat>();
foreach(var c in cats)
{
Console.WriteLine("{0} purrs at {1}", c.Name, c.PurrVolume);
}
我会得到一个异常"元素BarkVolume与类Cat的任何字段或属性不匹配"。
当然,如果我将查询更改为: var cats = collection.AsQueryable<Cat>().Where(x=>x is Cat);
那么没问题,但是有一个警告,说明 x 是 Cat 总是正确的。
驱动程序没有在鉴别器上注入测试是否有特殊原因_t
这是一个设计决策(在工作了一段时间后,我同意)。要指定_t
过滤器,您可以使用比x => x is Cat
更干净的OfType
扩展方法。
在MongoDB C#驱动程序中,几乎所有内容都有类型化和非类型化选项。键入的选项只是为了舒适起见,它们不会更改生成的查询。当您真正关心查询性能和索引利用率时,这是一件好事。
例如,如果您使用仅特定类型具有的属性进行查询,则无需添加OfType
(以及生成的_t
筛选器),并且如果您这样做,查询引擎可能会使用您可能不希望它执行的_t
索引。