I want to convert DataTable with below sample Data
Employee subject1 subject2 subject3 .......
1 100 80 60......
2 90 70 70...
into
List.
Where Employee Object is as follows..
public class Employee
{
public int EmpId { get; set;}
public Dictionary<string,decimal> SubjectMarks;
}
Can anyone help me in converting this Datatable to List in c sharp or using linq.
So the dynamic subject-columns start at index 1 and end at table.Columns-Count-1. Then i would create an array of these columns first. Then you can use Select + ToDictionary + ToList:
DataColumn[] subjectColumns = table.Columns.Cast<DataColumn>().Skip(1).ToArray();
List<Employee> employee = table.AsEnumerable()
.Select(r => new Employee
{
EmpId = r.Field<int>("Employee"),
SubjectMarks = subjectColumns.Select(c => new
{
Subject = c.ColumnName,
Marks = r.Field<decimal>(c)
})
.ToDictionary(x => x.Subject, x => x.Marks)
}).ToList();
Assuming that the type of the columns are already int for the ID and decimal for the marks. Otherwise use int.Parse and decimal.Parse to convert them.
var list = new List<Employee>();
var id = table.Columns[0];
var marks = table.Columns.Cast<DataColumn>().Skip(1).ToArray();
foreach (DataRow row in table.Rows)
{
var obj = new Employee { EmpId = (int) row[id] };
var dict = new Dictionary<string,decimal>();
foreach (var mark in marks)
{
dict[mark.ColumnName] = (decimal)row[mark];
}
obj.SubjectMarks = dict;
list.Add(obj);
}
Instead of using a Dictionary, then you can you List to add subject grades
Try this:
public class Employee
{
public int EmpId { get; set;}
public List<string> SubjectMarks { get; set;}
}
var empList = (from emp in dtEmployeeList.AsEnumerable()
select new Employee()
{
EmpId = (int) emp["Employee"],
SubjectMarks = List<string>()
{
emp["subject1"].ToString(),
emp["subject2"].ToString(),
emp["subject3"].ToString()
}
}).ToList()
You can do like this:
System.Data.DataTable table = // your table
List<Employee> result =
table.AsEnumerable().Select(i => new Employee()
{
EmpId = i.Field<int>("Employee"),
SubjectMarks = { { "subject1", i.Field<decimal>("subject1") } ,
{ "subject2", i.Field<decimal>("subject2") } ,
{ "subject3", i.Field<decimal>("subject3") } }
}).ToList();
You'll need to make sure you have a reference to System.Data.DataSetExtensions. And don't forget to add the using System.Data.
Related
I have following code, In which there are list of students , and I want to sort the students first by value column which contains decimal values and after that I want to sort the already sorted list with same column but with different values . Just for understanding , I changed values using foreach loop in the below example.
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var students = new List<Student>()
{
new Student() { StudentId=1,Name = "Alice", Appd = 10, Value = 3.5 },
new Student() { StudentId=2,Name = "Bob", Appd = 10, Value = 3.7 },
new Student() { StudentId=3,Name = "Raul", Appd = 10, Value = 0.1 },
new Student() { StudentId=4,Name = "Charlie", Appd = 0, Value = 3.6 },
new Student() { StudentId=5,Name = "Dave", Appd = 0, Value = 3.9 },
new Student() { StudentId=6,Name = "Emma", Appd = 0, Value = 3.8 }
};
var orderedFields = students.OrderByDescending(x => x.Value);//5,6,2,4,1,3
foreach ( Student s in orderedFields )
{
s.Value = 120;
}
orderedFields = orderedFields.ThenByDescending(x => x.Value);
var newlist1 = orderedFields.Select(X => X.StudentId).ToList();
}
}
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public int Appd { get; set; }
public double Value { get; set; }
}
}
but as soon I change the Value column values it start to change the order of items in list , and if I take this in another list then I will be not able to use the ThenByDescending feature results.
This is sample code to simplify the problem , in real example these columns name come from Database and based on those columns I want to sort the list, first by first column and then by another columns mentioned. For example in MySQL it will be something like this order by col1 desc, col2 desc.
As everybody is comments is discussing the clone and then sort again the list . so here is issue with that approach.
#1. First Set sorting values in Value column for each student :
Value column first contains for each student either 1 or 0 depending on its enrollment date from the cut off date.
#2 Then on same Value column there is CGPA for each student so student should be sorted based on that.
In short all students who apply before cut off date should appear
first and then sort by descending CGPA and then students who apply
after cut off date but those also should come in descending order of
CGPA.
problem is I have only one column here for values, on which need to be sort.
Second edit :
if (_trackConfigManager.RankDependentOnFields.Any())
{
infoFields.ForEach(x => x.PropertyToCompare = _trackConfigManager.RankDependentOnFields.FirstOrDefault().FieldId);
//Order the table withrespect to the firstfield
var orderedFields = infoFields.OrderByDescending(x => x.Value);
//Then skip the first element and order the rest of the fields by descending.
foreach (var field in __trackConfigManager.RankDependentOnFields.RemoveFirst())
{
infoFields.ForEach(x => x.PropertyToCompare = field.FieldId);
orderedFields = orderedFields.ThenByDescending(x => x.Value);
}
//Format a studentId, Rank dictionary from the above orderded table
int rank = 1 + GetMaxRank(programId, statusId);
}
and RankAggregate class as follow :
public class RankAggregate
{
public student_highschool_info HsInfoObj { get; set; }
public student_interview_info IntInfoObj { get; set; }
public student StuObj { get; set; }
private student_program SpObj { get; set; }
public string PropertyToCompare { get; set; }
public bool IsDateTimeField { get; set; }
public long StudentId { get; set; }
public int Choice { get; set; }
public double Value
{
get
{
var tokens = PropertyToCompare.Split(new char[] {':'});
if (tokens.Count() > 1)
{
PropertyToCompare = (Choice == 1)
? "student_interview_FirstPrgTotalScore"
: (Choice == 2) ? "student_interview_SecondPrgTotalScore" : "dummy";
}
var fldInfo = ReflectionUtility.GetPublicPropertyName(typeof(student_highschool_info), PropertyToCompare);
if (fldInfo != null)
{
if (HsInfoObj == null)
return 0;
IsDateTimeField = (fldInfo.PropertyType == typeof(DateTime?));
if (IsDateTimeField)
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student_highschool_info),
PropertyToCompare, HsInfoObj) ?? 0;
var dt = DateTime.Parse(val1.ToString());
return -Convert.ToDouble(dt.Ticks);
}
else
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student_highschool_info),
PropertyToCompare, HsInfoObj) ?? 0;
return Convert.ToDouble(val1);
}
}
fldInfo = ReflectionUtility.GetPublicPropertyName(typeof(student_interview_info), PropertyToCompare);
if (fldInfo != null)
{
if (IntInfoObj == null)
return 0;
IsDateTimeField = (fldInfo.PropertyType == typeof(DateTime?));
if (IsDateTimeField)
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student_interview_info),
PropertyToCompare, IntInfoObj) ?? 0;
var dt = DateTime.Parse(val1.ToString());
return -Convert.ToDouble(dt.Ticks);
}
else
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student_interview_info),
PropertyToCompare, this.IntInfoObj) ?? 0;
return Convert.ToDouble(val1);
}
}
fldInfo = ReflectionUtility.GetPublicPropertyName(typeof(student), PropertyToCompare);
if (fldInfo != null)
{
if (StuObj == null)
return 0;
IsDateTimeField = (fldInfo.PropertyType == typeof(DateTime?));
if (IsDateTimeField)
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student),
PropertyToCompare, StuObj) ?? 0;
var dt = DateTime.Parse(val1.ToString());
return -Convert.ToDouble(dt.Ticks);
}
else
{
var val1 = ReflectionUtility.GetValueOfPublicProperty(typeof(student),
PropertyToCompare, this.StuObj) ?? 0;
return Convert.ToDouble(val1);
}
}
return 0.0;
}
}
public RankAggregate(long studentId, student_highschool_info _hsInfo, student_interview_info _intInfo, student _profileInfo, student_program _spInfo)
{
StudentId = studentId;
HsInfoObj = _hsInfo;
IntInfoObj = _intInfo;
StuObj = _profileInfo;
SpObj = _spInfo;
if (SpObj != null)
{
Choice = SpObj.choice;
}
}
}
Don't know why can't you add another field to the Student class, anyway since you can't do that, you have to fix these values in some places, for example using a tuple:
var studentsWithValues = students.Select(s => (s, s.Value))
.ToList();
Then after changing the values, you can sort the above array:
var orderedFields = studentsWithValues.OrderByDescending(t => t.Value)
.ThenByDescending(t => t.s.Value)
.Select(t => t.s)
Update for uncertain columns
Bind each student object with a list of values:
var studentsWithValues = students.Select(s => new
{
Student = s,
Values = new List<double> { s.Value }
})
.ToList();
After the values are updated, append each value to the binded list:
UpdateValues();
studentsWithValues.ForEach(t => t.Values.Add(t.Student.Value));
Then you can sort these values:
var e = studentsWithValues.OrderByDescending(t => t.Values[0]);
var valueCount = studentsWithValues.First().Values.Count;
for (int i = 1; i < valueCount; i++)
{
int j = i;
e = e.ThenByDescending(t => t.Values[j]);
}
var orderedFields = e.Select(t => t.Student);
Short answer
Use:
var orderedStudents = students
.OrderByDescending(student => student.Value)
.ToList();
foreach (Student student in orderedStudents) etc.
Longer answer
Your orderedFields is not a list, nor a sequence. It is an object that can be enumerated. It has not been enumerated yet. In other words: it is not a Collection<T>, it is an IEnumerable<T>. Usually in descriptions you'll find the phrases: delayed execution or deferred execution.
When you execute foreach (Student s in orderedFields), you start to enumerate the items in students. You don't enumerate the items in the original order, you enumerate them ordered by .Value.
but as soon I change the Value column values it start to change the order of items in list
So, the next time you enumerate orderedFields, the items in students are enumerated again, and ordered again by the changed value of .Value.
If you want to change the source of the items in your LINQ statement, you have to execute the delayed execution by calling one of the LINQ methods that doesn't return IEnumerable<T>, like ToList(), ToArray(), ToDictionary(), but also FirstOrDefault(), Sum(), Count(), Any()
By calling one of the non-delayed methods, the source is enumerated and the result is put in a new object. If you change the items in the new object, and use this new object as source for your next LINQ-statement, then the order of the new object is used, not the order in the original object.
Careful: if you put the references of the original items in the new List, and you change the values, you change the original items. If you don't want that, use a Select(student => new {...}) to put the values in a new object. If you change those values, the original students are not affected.
I have a model (sample below), and sample data with desired output..
I have also given two ways to populate model which will give desired output but for somereason,
looks like I am missing something....
Not able to figure out what is the issue here...
need inputs in correcting approach 1 or approach 2 or you can also suggest any other approach which will help populate model in below response..
models
class Emp
{
public int id {get;set;}
public int Name {get;set;}
public List<cardType> cardTypes {get;set;}
}
class cardType
{
public int name {get;set;}
public DateTime Expiry {get;set;}
}
sample data (Data is returned in 1 table only)
id Name cardTypeName exp
1 a Amex 1010
1 a City 2010
desired output
<Emp>
<ID>1</id>
<name>1</name>
<cardTypes>
<cardType>
<Name> Amex </Name>
<exp> 1010 </exp>
</cardType>
<cardType>
<Name> City </Name>
<exp> 2010 </exp>
</cardType>
<cardTypes>
</Emp>
approach 1
(dataTable.AsEnumerable()
.GroupBy(r => r.ItemArray[1])
.Select(grp => new Emp()
{
id = r.itemarray[1],
name = r.itemarray[1],
cardTypes = grp.Select(t => new cardType()
{
field 1,
field 2
}).ToList()
}));
approach 2
return (from DataRow dr in dataTable.Rows
select new Emp
{
id = "",
name= "",
cardTypes = dataTable.AsEnumerable()
.Select(x => new cardType
{
name = ""
exp = ""
}).ToList(),
});
try this
return dataTable.AsEnumerable()
.GroupBy(x => x.Id)
.Select(x => new
{
id = x.Key,
name = x.Key,
cardTypes = x.Select(t => new
{
name = t.Name,
exp = t.Exp
})
});
This should work for you considering you will change the Expiry field in cardType to int
var results =
dt.AsEnumerable()
.GroupBy(row => row.ItemArray[0])
.Select(rows => new Emp
{
id = rows.Key,
name = rows.Key,
cardTypes = rows.Select(row => new cardType {Name = row.ItemArray[2], Expiry = row.ItemArray[3]})
});
If you desire to have DateTime, then decide how to convert. For example:
cardTypes = rows.Select(row => new cardType {Name = row.ItemArray[2], Expiry = new DateTime(row.ItemArray[3],1,1)})
If you want to serialize to xml your models, you should mark your models with [Serializable] attribute and just use XmlSerializer.
[Serializable]
class Emp
{
public int id {get;set;}
public int Name {get;set;}
public List<cardType> cardTypes {get;set;}
}
[Serializable]
class cardType
{
public int name {get;set;}
public DateTime Expiry {get;set;}
}
After that you can use following code:
static Dictionary<int, Emp> ConvertToDict(DataTable dt)
{
Dictionary<int, Emp> emps = new Dictionary<int, Emp>();
foreach (var dr in dt.AsEnumerable())
{
var id = (int)dr["ID"];
var name = (string)dr["Name"];
var cardTypeName = (string)dr["CardTypeName"];
var exp = (int)dr["Exp"];
Emp emp;
var cardType = new CardType { Name = cardTypeName, Exp = exp };
if (emps.TryGetValue(id, out emp))
{
emp.CardTypes.Add(cardType);
}
else
{
emps.Add(id, new Emp { ID = id, Name = name, CardTypes = new List<CardType> { cardType } });
}
}
return emps;
}
static List<string> Serialize<T>(IEnumerable<T> entities) where T:new()
{
var ser = new XmlSerializer(typeof(T));
var serializedEntities = entities.Select(entity =>
{
using (var sw = new StringWriter())
{
ser.Serialize(sw, entity);
return sw.ToString();
}
}).ToList();
return serializedEntities;
}
I'm doing some work on an old Winforms grid and i have two Models that i am trying to flatten and assign to a DataGridView.
Here are my sample models.
public class StockItem
{
public string StockName { get; set; }
public int Id { get; set; }
public List<Warehouse> Warehouses { get; set; }
}
public class Warehouse
{
public string WarehouseName { get; set; }
public int Id { get; set; }
}
The data works in a way that a warehouse must first be created and then assigned to each StockItem. A StockItem may have all the warehouses or may only have one.
I need to flatten the data so that the grid shows the StockName and then all the associated warehouses for the stock item.
Example
StockCode1 Warehouse1 Warehouse2 Warehouse3
StockCode2 Warehouse1 Warehouse2
StockCode2 Warehouse1 Warehouse3
I've attempted to do this via a Linq query but can only get a record per StockItem\Warehouse.
You can achieve it by creating a DataTable that yon can easily use as a source for the gridview. First add all columns and then for each stock add the warehouses:
var warehouseNames =
stocks
.SelectMany(x => x.Warehouses.Select(y => y.WarehouseName)).Distinct();
var dt = new DataTable();
dt.Columns.Add("StockCode");
foreach (var name in warehouseNames)
{
dt.Columns.Add(name);
}
foreach (var stock in stocks)
{
var row = dt.NewRow();
row["StockCode"] = stock.Id;
foreach (var warehouse in stock.Warehouses)
{
row[warehouse.WarehouseName] = warehouse.Id;
}
dt.Rows.Add(row);
}
I do not recommend it, but you can use dynamic objects to create objects with the shape you want. Doing this is not a common C# pattern. This is more common in languages like Python or Javascript.
C# is a strongly typed language and venturing into the world of dynamic objects should only be considered when absolutely necessary (think parsing a json blob). I strongly consider you reevaluate what you need to do and approach it from a different angle.
Something like this:
var availableWarehouses = new [] {
new Warehouse {
WarehouseName = "Warehouse1",
Id = 1
},
new Warehouse {
WarehouseName = "Warehouse2",
Id = 2
},
new Warehouse {
WarehouseName = "Warehouse3",
Id = 3
}
};
var stocks = new [] {
new StockItem {
StockName = "StockCode1",
Id = 1,
Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[1], availableWarehouses[2] }
},
new StockItem {
StockName = "StockCode2",
Id = 2,
Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[1] }
},
new StockItem {
StockName = "StockCode3",
Id = 3,
Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[2] }
}
};
var flatten = stocks.Select(item => new {
StockName = item.StockName,
WarehousesNames = availableWarehouses.Select(warehouse => item.Warehouses.Contains(warehouse) ? warehouse.WarehouseName : " ")
.Aggregate((current, next) => current + "\t" + next)
});
foreach(var item in flatten) {
Console.WriteLine("{0}\t{1}", item.StockName, item.WarehousesNames);
}
That should give you what you need:
var flattened = stockItems
.Select(x => new {
StockName = x.StockName,
WarehouseNames = x.Warehouses
.Select(y => y.WarehouseName)
.ToList() })
.ToList();
It will result in a collection of items that contain StockName and a list of WarehouseName strings. ToList added to enumerate the query.
For these sample data:
List<StockItem> stockItems = new List<StockItem>
{
new StockItem
{
StockName ="A",
Id = 1,
Warehouses = new List<Warehouse>
{
new Warehouse { Id = 1, WarehouseName = "x" },
new Warehouse { Id = 2, WarehouseName = "y" }
}
},
new StockItem
{
StockName = "B",
Id = 2,
Warehouses = new List<Warehouse>
{
new Warehouse { Id = 3, WarehouseName = "z" },
new Warehouse { Id = 4, WarehouseName = "w" }
}
}
};
I've got the following result:
I am trying to load the data from datatable to objects using Linq. Below is my scenario. I have below table structure and data:
seq name id class
1 Rajesh 101 B
1 kumar 102 B
1 sandeep 104 A
2 Myur 105 B
2 Bhuvan 106 C
3 Siraz 107 A
Below is my class structures
public class student
{
public string name {get;set;}
public string id { get; set; }
public string meritClass { get; set; }
}
public class stdGroup
{
public int seqId{get;set;}
public List<student> students;
}
As a final output I should get a Student constructed for each seq. stdGroup object should be created grouping by seq [three objects].
Example:
stdGroup object 1 would contain 3 student objects
stdGroup object 2 would contain 2 student objects
Can anyone please help me.
This should do what you need (assuming by DataTable you mean DataTable):
List<stdGroup> stdGroups = myDataTable
.AsEnumerable()
.GroupBy(a => a.Field<int>("Seq"), a => new student() { id = a.Field<string>("Id"), name = a.Field<string>("name"), meritClass = a.Field<string>("class") })
.Select(a => new stdGroup() { seqId = a.Key, students = a.ToList() })
.ToList();
To break it down, firstly, get the datatable rows into a state where we can use linq,
.AsEnumerable()
Now, do the groupings - selecting seq as the key for the group, and build a student object for every entry, which will get assigned to the corresponding group.
.GroupBy(a => a.Field<int>("Seq"), a => new student() { id = a.Field<string>("Id"), name = a.Field<string>("name"), meritClass = a.Field<string>("class") })
Now, for each group create the stdGroup object, and populate the seq property from our group keys, and take the content of each group, and assign that to the students property.
.Select(a => new stdGroup() { seqId = a.Key, students = a.ToList() })
Finally, and optionally, convert to a list instead of enumerable.
.ToList();
You can also check out my implementation:
public class dbStudent
{
public int seq;
public string name;
public int id;
public string meritClass;
}
public class student
{
public string name { get; set; }
public int id { get; set; }
public string meritClass { get; set; }
}
public class stdGroup
{
public int seqId { get; set; }
public List<student> students { get; set; }
}
class Program
{
static void Main(string[] args)
{
var dbStudebts = new List<dbStudent>();
dbStudebts.Add(new dbStudent { seq = 1, name = "Rajesh", id = 101, meritClass = "B" });
dbStudebts.Add(new dbStudent { seq = 1, name = "kumar", id = 102, meritClass = "B" });
dbStudebts.Add(new dbStudent { seq = 1, name = "sandeep", id = 104, meritClass = "A" });
dbStudebts.Add(new dbStudent { seq = 2, name = "Myur", id = 105, meritClass = "B" });
dbStudebts.Add(new dbStudent { seq = 2, name = "Bhuvan", id = 106, meritClass = "C" });
dbStudebts.Add(new dbStudent { seq = 3, name = "Siraz", id = 107, meritClass = "A" });
var result = (from o in dbStudebts
group o by new { o.seq } into grouped
select new stdGroup()
{
seqId = grouped.Key.seq,
students = grouped.Select(c => new student()
{
name = c.name,
id = c.id,
meritClass = c.meritClass
}).ToList()
}).ToList();
}
}
I have this dictionary mappings declared as a Dictionary<string, HashSet<string>>.
I also have this method to do stuff on a hashset in the dictionary:
public void DoStuff(string key, int iClassId){
foreach (var classEntry in
from c in mappings[key]
where c.StartsWith(iClassId + "(")
select c)
{
DoStuffWithEntry(classEntry);
}
}
private void DoStuffWithEntry(string classEntry){
// Do stuff with classEntry here
}
In one case, I need to do this on a number of keys in the mappings dictionary, and I was thinking it was better to rewrite and filter on a list of keys instead of calling DoStuff for each key to optimise the execution.
Currently I do this:
DoStuff("key1", 123);
DoStuff("key2", 123);
DoStuff("key4", 123);
DoStuff("key7", 123);
DoStuff("key11", 123);
Logically something like this instead of calling DoStuff for each (FilterOnKeys is not a method - just what I want...):
foreach (var classEntry in
from c in mappings.FilterOnKeys("key1", "key2", "key4", "key7", "key11")
where c.StartsWith(iClassId + "(")
select c)
{
DoStuffWithEntry(classEntry);
}
It sounds like you want:
string[] keys = { "key1", "key2", ... }
var query = from key in keys
from c in mappings[key]
...;
foreach (var entry in query)
{
...
}
(I would personally use a separate variable for the query just for readability - I'm not too keen on the declaration bit of a foreach loop getting huge.)
I'm using LINQ as per your requirement
var temp = eid.Select(i =>
EmployeeList.ContainsKey(i)
? EmployeeList[i]
: null
).Where(i => i != null).ToList();
The Complete C# Source Code is
public class Person
{
public int EmpID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string Gender { get; set; }
}
void Main()
{
Dictionary<int, Person> EmployeeList = new Dictionary<int, Person>();
EmployeeList.Add(1, new Person() {EmpID = 1, Name = "Peter", Department = "Development",Gender = "Male"});
EmployeeList.Add(2, new Person() {EmpID = 2, Name = "Emma Watson", Department = "Development",Gender = "Female"});
EmployeeList.Add(3, new Person() {EmpID = 3, Name = "Raj", Department = "Development",Gender = "Male"});
EmployeeList.Add(4, new Person() {EmpID = 4, Name = "Kaliya", Department = "Development",Gender = "Male"});
EmployeeList.Add(5, new Person() {EmpID = 5, Name = "Keerthi", Department = "Development",Gender = "Female"});
List<int> eid = new List<int>() { 1,3 };
List<Person> SelectedEmployeeList = new List<Person>();
var temp = eid.Select(i =>
EmployeeList.ContainsKey(i)
? EmployeeList[i]
: null
).Where(i => i != null).ToList();
}
You can make use something like this
var ids = {1, 2, 3};
var query = from item in context.items
where ids.Contains(item.id )
select item;
in your case
string[] keys = { "key1", "key2", ... }
var query = from key in keys
where ids.Contains(keys )
select key ;
you could linq your way through mappings
EDITED i missed a nesting level, he wants to query hashsets not the whole dictionary
public void DoStuff(IEnumerable<string> key, int iClassId)
{
mappings.Where(i=>key.Contains(i.Key)).ToList().ForEach(obj=>
{
foreach (var classEntry in
from c in obj.Value
where c.StartsWith(iClassId + "(")
select c)
{
DoStuffWithEntry(classEntry);
}
}
changed key parameter and from c ... section.
you call it like this
string[] keys = new string[]{"key1", "key2", ... , "keyN"};
DoStuff(keys, 123);
this should work