我使用连接到Mongo 3.0.6服务器的Mongo C#驱动程序版本2.2.3。
鉴于Person类的MongoDb Collection(见下文),我想找到电子邮件地址为" not@home.com"的人。有些天真,我曾希望像tis这样的东西能起作用:
var people = database.GetCollection<Person>("People");
var person = from p in people.AsQueryable()
where p.Addresses.OfType<EmailAddress>().Any(e=>e.MailTo == "not@home.com")
但是在运行时,我会收到NotSupportedException
。表达式树不支持方法OfType。
是否有一种简单的方法来匹配元素(使用强类型)多态数组?
(这里是模特)
class Person
{
public Address[] Addresses {get;set;}
}
class Address
{
}
class Phone : Address
{
public string Number {get;set;}
}
class Email : Address
{
public string MailTo {get;set;}
}
我试图找到的示例文档是:
{
"_id" : ObjectId("56d76465b27c42eb491aa2e7"),
"Addresses" : [
{
"_t" : "Email",
"MailTo" : "not@home.com"
},
{
"_t" : "Phone",
"Number" : "555-1234"
}
]
}
答案 0 :(得分:1)
嗨现在在2.2.4中修复了 请参阅mongodb jira entry
答案 1 :(得分:0)
好吧,虽然C#驱动程序没有完全实现,但缺少很多功能,但在我看来,问题出在你的类结构中。
e.g。 Person对象的地址和地址可以是Phone或Email类型,也可以是两者。那是司机抱怨的地方,因为它无法理解可能有什么类型的物品。
由于它本质上更具动态性,因此我建议您使用BsonDocument类型进行查询,而不是强制转换为您想要的任何对象。说你没有多少选择来获得你的结果
选项#1:
如果执行以下代码:
var mailTo = "not@home.com";
var filter = Builders<BsonDocument>.Filter.ElemMatch("Addresses",
Builders<BsonDocument>.Filter.Eq("MailTo", mailTo));
var people = database.GetCollection<BsonDocument>("People");
var person = people.FindSync(filter).ToList();
您将在子文档中获得包含not@hotme.com
的记录。
选项#2:
如果您可以稍微改变模型,则可以充分利用linq查询。
public class Person
{
public ObjectId Id { get; set; }
public Address[] Addresses { get; set; }
}
public class Address
{
public string MailTo { get; set; }
public string Number { get; set; }
}
var mailTo = "not@home.com";
var filter = Builders<Person>.Filter.ElemMatch(e => e.Addresses,
address => address.MailTo == mailTo );
var people = database.GetCollection<Person>("People");
var person = people.FindSync<Person>(filter).ToList();
现在,person将持有一个或多个符合您条件的Person对象。