您好开始使用mongodb和c#,发现它非常酷,只是想知道查询的最佳方式
似乎有以下选项
var query = Query<Entity>.EQ(e => e.Id, id);
var entity = collection.FindOne(query);
VS
var entity = collection.Entity.AsQueryable().Single(x => x.Id == id)
现在第二个看起来对我来说更具吸引力了,但就性能和最佳实践而言,最新的差异是什么?推荐?
答案 0 :(得分:1)
您的第一个示例是使用驱动程序本机查询 - 基本上通过QueryDocument
帮助程序创建Query<T>
等。
你的第二个是使用Linq。
在幕后,这些都归结为生成相同的查询:
db.entity.find({_id: 'abc123'});
生成的QueryDocument被序列化为查询,在本例中为
{_id: 'abc123'}
根据linq docs:
仅支持可转换为等效MongoDB查询的LINQ查询。如果您编写的LINQ查询无法翻译,您将收到运行时异常,错误消息将指示查询的哪个部分不受支持。
对我来说,这表明有一些开销将LINQ查询转换为MongoDB查询...
我还没有对此进行测试,但我怀疑使用Query的性能略高一些
答案 1 :(得分:1)
第一种方法是构建查询然后用它来查找结果,实际上是Specification Pattern。
第二种方法是直接LINQ查询,.NET开发人员通常更熟悉。
规范模式为您提供了可重用的过滤逻辑。如果您经常需要按照相同的标准过滤集合,那么它非常有用 - 特别是如果需要将过滤器应用于来自各种存储库的集合。
这是一个可能使用它的快速示例(原谅任何粗略的代码,我已经离开C#一段时间了):
static class WidgetSpecification {
function Query<Widget> AvailableWidgets()
{
return new Query<Widget>.EQ(e =>
e.StartDate <= Date.Today
&& e.EndDate >= Date.Today
&& e.Active == true
&& e.InStock == true);
}
}
然后,在您的应用中您需要“可用小部件”的任何地方,您可以调用类似的内容:
{
...
var products = getProductsFromSomewhere();
var query = WidgetSpecifiation.AvailableWidgets();
var availableProducts = Products.Find(query);
...
}
如果您重新定义“可用小部件”的内容,您可以更新规范并让所有消费者的行为相同。