如何在MongoDB C#驱动程序中按后代属性筛选?

时间:2019-12-16 03:38:10

标签: c# mongodb inheritance

比方说,我有一个从Vehicle开始的类层次结构,有Car,Plane e.t.c.我想找回32辆最后一辆汽车,但是我不想看到特殊类型的汽车,例如冬季轮胎上的汽车。 “汽车”的字段为TireType。 这应该是一个简单的mongo查询,如下所示:

db.Vehicles.find({
    "userId" : ObjectId("5df1f2d1de064e5618be579c"),
    "tireType": {$ne: "Winter"},
}).sort({ "_id" : -1 }).limit(32)

但是我可以在C#中做什么来实现这一目标?我已经尝试了很多不同的方法,例如LINQ(不受支持):

from v in _db.Vehicles.AsQueryable()
where v.UserId == userId
let c = v as Car
where c == null || c.TireType != "Winter"
orderby ev.Id descending
select v;

FilterBuilder(无法转换):

using V = Builders<Vehicle>;
using C = Builders<Car>;

_db.Vehicles
.Find(V.Filter.And(C.Filter.Ne(x=>x.TireType, "Winter"), V.Filter.Eq(x=>x.UserId, userId))
.SortByDescending(x => x.Id)
.Limit(32);

我可以使用BsonDocument来做到这一点,但我希望将其具体化到模型类中……为此找不到很好的答案...

1 个答案:

答案 0 :(得分:1)

尝试一下:

    var vehicles = collection.Find(
                       Builders<Vehicle>.Filter.Eq(v => v.UserID, "xxx") &
                       Builders<Vehicle>.Filter.Ne("TireType", "winter"))
                   .SortByDescending(v=>v.Id)
                   .Limit(32)
                   .ToList();

这是一个测试程序:

using MongoDB.Entities;
using MongoDB.Entities.Core;

namespace StackOverflow
{
    [Name("Vehicles")]
    public class Vehicle : Entity
    {
        public string Type { get; set; }
        public string UserID { get; set; }
        public string Color { get; set; }
    }

    [Name("Vehicles")]
    public class Car : Vehicle
    {
        public string TireType { get; set; }
    }

    [Name("Vehicles")]
    public class Truck : Vehicle
    {
        public string FuelType { get; set; }
    }

    public class Program
    {
        private static void Main(string[] args)
        {
            new DB("test", "localhost");

            (new Car { UserID = "xxx", Type = "car", Color = "red", TireType = "summer" }).Save();
            (new Car { UserID = "xxx", Type = "car", Color = "white", TireType = "winter" }).Save();
            (new Truck { UserID = "xxx", Type = "truck", Color = "black", FuelType = "diesel" }).Save();

            var result = DB.Find<Vehicle>()
                           .Match(f =>
                                  f.Eq(v => v.UserID, "xxx") &
                                  f.Ne("TireType", "winter"))
                           .Sort(v => v.ID, Order.Descending)
                           .Limit(32)
                           .Execute();

            //var result = DB.Collection<Vehicle>().Find(
            //                Builders<Vehicle>.Filter.Eq(v => v.UserID, "xxx") &
            //                Builders<Vehicle>.Filter.Ne("TireType", "winter"))
            //               .Limit(32)
            //               .ToList();
        }
    }
}