我有一个可枚举的如下:
IEnumerable<dynamic> collection = new
{
column1 = "1", column2 = "name", column3= "somevalue"
},
new
{
column1 = "2", column2 = "name2", column3= "somevalue2"
},
new
{
column1 = "3", column2 = "name3", column3= "somevalue3"
}
等等......动态类型中的列数也可能不同。列的数量可能更多或更少。
现在,如果我想搜索此IEnumerable集合,例如somevalue2,我需要以下信息 在列“column2”中的第2行(假设column1始终是主键)中找到。 这是将此动态集合转换为数据结构(.NET List / Collection / Hashtable等)的最佳方式,也是查询集合中信息的最佳方式。该集合最多将是一页数据(25行)。 任何代码片段和数据结构都可以实现超快速有效的数据搜索方式。假设搜索词是“包含”匹配而不是完美匹配。
答案 0 :(得分:3)
这些是匿名类型;匿名类型是一种编译器功能,因此在编译时布局是 fixed rigid ,因此它们不会发生变化。我建议:不要使用dynamic
。例如:
var arr = new[] {
new { column1 = "1", column2 = "name", column3= "somevalue" },
new { column1 = "2", column2 = "name2", column3= "somevalue2" },
new { column1 = "3", column2 = "name3", column3= "somevalue3" }
};
这是强类型和明确定义的。您可以使用常规操作,例如:
var item2 = arr.FirstOrDefault(x => x.column1 == "2");
再次,所有静态类型。
如果你想搜索所有列,那么我会建议像字典更好的东西:
var arr = new[] {
new Dictionary<string,string> { {"column1", "1"}, ... },
new Dictionary<string,string> { {"column1", "2"}, ... },
new Dictionary<string,string> { {"column1", "3"}, ... },
};
因为您可以查看.Values.Contains(...)
编辑:通过评论我认为我更清楚地理解它;我正在想象一个返回IEnumerable<dynamic>
的opaque方法,它实际上是POCO类型(不是动态类型),我们想检查匹配的字符串成员(任意名称)。我们应该能够通过反射来做到这一点,但FastMember会使速度更快:
static void Main()
{
string search = "ame2";
int rowIndex = 0;
string[] names = null;
TypeAccessor accessor = null;
foreach(object row in GetData())
{
if(names == null)
{ // first row; get the property-names and build an accessor
names = (from prop in row.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
where prop.PropertyType == typeof (string)
select prop.Name).ToArray();
accessor = TypeAccessor.Create(row.GetType());
}
foreach(var name in names)
{
var val = accessor[row, name] as string;
if(val != null && val.Contains(search))
{
Console.WriteLine("row {0}, col {1}, val {2}", rowIndex, name, val);
}
}
rowIndex++;
}
}
static IEnumerable<dynamic> GetData()
{
yield return new {column1 = "1", column2 = "name", column3 = "somevalue"};
yield return new {column1 = "2", column2 = "name2", column3 = "somevalue2"};
yield return new {column1 = "3", column2 = "name3", column3 = "somevalue3"};
}
答案 1 :(得分:0)
如果你真的希望它们是每个项目中具有不同列的动态对象,你可以这样声明:
IEnumerable<dynamic> collection = new dynamic[]
{
new
{
column1 = "1",
column2 = "name",
column3 = "somevalue"
},
new
{
column1 = "2",
column2 = "name2"
},
new
{
column1 = "3",
column2 = "name3",
column3 = "somevalue3",
column4 = "fourthValue"
}
};
将其转换为列表很简单:
// create a list
var list = new List<dynamic>(collection);
查找项目有点复杂,因为属性可能不存在:
// find an item
var itemOne = collection.Where(i =>
{
try
{
if (i.column1 == "1")
{
return true;
}
}
catch
{
// ignore error, column doesn't exist
}
return false;
});
答案 2 :(得分:0)
我不知道你的IEnumerable下面究竟隐藏了什么,但最近我不得不搜索Dapper从某些查询返回的结果,这些查询作为动态的IEnumerable返回(这是我遇到这个问题的方式)。
在我的情况下,解决方案是施展我的
IEnumerable<dynamic>
作为
IEnumerable<IDictionary<String, Object>>
但是我认为它只适用于数据取样,如:
db.Connection.Query(myQuery)
对于这个特殊问题,这样的事情可能会起作用(尚未测试):
IEnumerable<IDictionary<String, Object>> data = YourData.Cast<IDictionary<String, Object>>();
var row = data.SingleOrDefault(x => x.Where(y => y.Value.ToString() == "somevalue2"));
我不知道这会有多快,但我希望它会帮助你(或某人,看到这个问题刚刚发布)。