MongoDB C# 组合字段

MongoDB C# Combining Fields


计划:
所以现在我基本上想要的是从 class 中取出我的属性,让用户选择一些,然后从 MongoDB 中拉出一个仅包含这些属性的列表。

代码:
这里是方法开始的地方:

private void DoStuffExecute(object obj)
        {
            Class class= new Class();
            ExtractClass(class);

            if (propList != null)
            {
                var result = classService.DoStuff(propList);
            }
        }

在 "ExtractClass()" 中,正在从 Class 中拉出属性。

void ExtractClass(object obj)
    {
        foreach (var item in obj.GetType().GetProperties())
        {
            propList.Add(item.Name);
        }
    }

最后在 "classService.DoStuff()" 中,我尝试设置 "fields"。

    public List<class> DoStuff(List<string> Props)
            {
                try
                {
                    var filter = Builders<class>.Filter.Empty;

                    var fields = Builders<class>.Projection.Include(x => x.ID);

                    foreach (var item in Props)
                    {
                        string str = "x.";
                        str += item.ToString();

                        fields = Builders<class>.Projection.Include(x => str);
                        fields = Builders<class>.Projection.Include(x => item);
                    }

                    var result = MongoConnectionHandler.MongoCollection.Find(filter).Project<class>(fields).ToList();

                return result;

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    var result = new List<class>();
                    return result;
                }
            }

当我 运行 程序时,它给了我一个 "Unable to determine the serialization information for x=> value"... 因为我给了它一个字符串。

问题: 有没有人知道如何修复上面的代码,甚至让计划以另一种方式工作?

谢谢。

首先:您正在使用这样的代码行: var filter = Builders<class>.Filter.Empty; 这是不可能的,因为 class 是 c# 中的保留关键字 (https://msdn.microsoft.com/en-us/library/x53a06bb.aspx) 我想,它是你的模特,我会把它说成 Model class.

Include Filter 需要 Expression 作为参数,而不是字符串,您应该将 is 作为表达式构造。这是第二件事。第三,你应该将你的包含组合成一个链,所以你从字符串列表创建包含过滤器的部分应该是这样的:

 var filter = Builders<Model>.Filter.Empty;

 var fields = Builders<Model>.Projection.Include(x => x.Id);

 foreach (var item in Props)
 {
       var par = Expression.Parameter(typeof(Model));
       var prop = Expression.Property(par, item);
       var cast = Expression.Convert(prop, typeof(object));
       var lambda = Expression.Lambda(cast, par);                                         
       fields =  fields.Include((Expression<Func<Model, object>>)lambda);              
 }

我将所有表达式分开以便更好地理解:首先创建参数 (x=>),然后添加 属性 (x=>x.Property1),然后将其转换为 object,然后从中创建 Lambda Expression

现在是最后一部分:您不需要全部,Include 函数可以获得一个字符串作为参数。所以你可以代替所有表达式调用写这个:

fields =  fields.Include(item);