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);
计划:
所以现在我基本上想要的是从 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);