计划:
所以现在我基本上想要的是将我的属性从类中取出,让用户选择一些,然后从MongoDB中仅使用那些属性的List。
守则:
这是方法开始的地方:
private void DoStuffExecute(object obj)
{
Class class= new Class();
ExtractClass(class);
if (propList != null)
{
var result = classService.DoStuff(propList);
}
}
在“ExtractClass()”中,Propertys被拉出了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;
}
}
当我运行程序时,它给了我“无法确定x =&gt;值的序列化信息”......因为我给它一个字符串。
问题:
有没有人有一个想法如何修复上面的代码,甚至使计划以另一种方式工作?
谢谢。
答案 0 :(得分:0)
首先:您使用以下代码行:var filter = Builders<class>.Filter.Empty;
这是不可能的,因为class
是c#(https://msdn.microsoft.com/en-us/library/x53a06bb.aspx)中的保留关键字我认为,它是&#39 ;是你的模型,我会谈论它是关于Model
类的。
包含过滤器需要Expression
作为参数,而不是字符串,您应该构造为表达式。这是第二件事。第三,你应该将你的包括为一个链,所以你从字符串List创建包含过滤器的部分应该是这样的:
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函数可以获得jsut字符串作为参数。所以你可以代替所有表达式调用写下这个:
fields = fields.Include(item);