简体   繁体   English

如何在C#类的计算字段上过滤Bson Document?

[英]How to filter Bson Document on a computed field of a C# class?

I have several classes that I need to store in a MongoDb collection, these classes have a common base class and common interface defining the common fields. 我有几个需要存储在MongoDb集合中的类,这些类具有公共基类和定义公共字段的公共接口。 Every class have a computed field with the same name but with different implementations. 每个类都有一个具有相同名称但具有不同实现的计算字段。 When I try to query on that field I get the message that the field is not supported 当我尝试查询该字段时,我收到一条消息,提示不支持该字段

I'm running this on a .Net Core 2.2 console application with the latest MongoDb Driver 我正在使用最新的MongoDb驱动程序在.Net Core 2.2控制台应用程序上运行此程序

Interface: 接口:

 public interface ITask
    {
        ObjectId Id { get; set; }
        TaskStatus Status { get; set; }
        DateTime Timestamp { get; set; }
        string UserId { get; set; }
        string ComputedField{ get; }
    }

Base Class: 基类:

public abstract class BaseTask : ITask
    {
        [BsonId(IdGenerator = typeof(ObjectIdGenerator))]
        public ObjectId Id { get; set; }
        [BsonElement("Status")]
        public TaskStatus Status { get; set; }
        [BsonElement("Timestamp")]
        public DateTime Timestamp { get; set; }
        [BsonElement("UserId")]
        public string UserId { get; set; }
        public virtual string ComputedField
        {
            get { return CalculateMD5Hash(Id.ToString()); }
        }
}

Actual class that give me the problem 给我问题的实际课堂

public class MyTask : BaseTask
    {

        [BsonElement("Field1")]
        public Guid Field1{ get; set; }


        [BsonElement("ComputedField")]
        public override string ComputedField
        {
            get { return CalculateMD5Hash($"ABC{Field1.ToString()}"); } 
        }

    }

Wrapper that call the MongoDb layer 调用MongoDb层的包装器

public class TaskService<T> : ITaskService<T> where T : ITask
    {
        private readonly IPersistanceLayer<ObjectId, object> _pl;


        public async Task<T> GetNextTask(string key)
        {
              var oee = _pl.Mongo.Filter<T>(x => x.ConcurrencyKey==key 
                , typeof(T).Name).OrderBy(x=> x.Timestamp).FirstOrDefault();
            return oee;
        }

    }

MongoDb Layer MongoDb层

 public IEnumerable<T> Filter<T>(System.Linq.Expressions.Expression<Func<T, bool>> lambda, string collection)
        {
            var filter = Builders<T>.Filter.Where(lambda);

            return _db.GetCollection<T>(collection).Find(filter).ToList();
        }

The error I get is 我得到的错误是

[ERR] {document}.ComputedField is not supported.

In the collection i see the document saved when I insert it but and the value of the computed filed is stored correctly, the only problem is when i try to query on that field 在集合中,当我插入文档时,我看到保存的文档,但是计算字段的值正确存储,唯一的问题是当我尝试查询该字段时

The problem was that I was looking in the wrong collection and casting to the wrong class 问题是我在寻找错误的收藏品并将其投射到错误的类上

public class TaskService<T> : ITaskService<T> where T : ITask
    {
        private readonly IPersistanceLayer<ObjectId, object> _pl;


        public async Task<T> GetNextTask(string key)
        {
              var nextTask= _pl.Mongo.Filter<T>(x => x.ConcurrencyKey==key 
                , typeof(T).Name).OrderBy(x=> x.Timestamp).FirstOrDefault();
            return nextTask;
        }

    }

In this method T was of the type BaseTask and not MyTask so my computed field was not there, I have corrected that and now it works 在此方法中,T的类型为BaseTask而不是MyTask,因此我的计算字段不存在,我已对此进行了更正,现在可以正常工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM