I have a list of Dictionary with same list of keys, but different value. Is there a way to write that to CSV file using the CSVHelper? I have the sample code below, but obviously it didn't work.
static void Main(string[] args)
{
List<Dictionary<String, String>> records = new List<Dictionary<string, string>>();
Dictionary<String, String> data1 = new Dictionary<String, String>();
data1.Add("Name1", "Value1");
data1.Add("Name2", "Value2");
records.Add(data1);
Dictionary<String, String> data2 = new Dictionary<String, String>();
data2.Add("Name1", "Value1");
data2.Add("Name2", "Value2");
records.Add(data2);
using (var writer = new StreamWriter("e:\\temp\\test.csv"))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(records);
//GEtting exception here
//CsvHelper.Configuration.CsvConfigurationException: 'Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?'
}
}
Is there any way around that?
Thanks!
I believe the only way to do it will be to write them out by hand.
using (var writer = new StreamWriter("e:\\temp\\test.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
var headings = new List<string>(records.First().Keys);
foreach (var heading in headings)
{
csv.WriteField(heading);
}
csv.NextRecord();
foreach (var item in records)
{
foreach (var heading in headings)
{
csv.WriteField(item[heading]);
}
csv.NextRecord();
}
}
Related
I have a csv data like this
Header1
Header2
Header3
...
ValueN
Key1
Value11
Value12
Value13
...
Value1N
Key2
Value21
Value22
Value23
...
Value2N
Key3
Value31
Value32
Value33
...
Value3N
...
...
...
...
...
...
KeyN
ValueN1
ValueN2
ValueN3
...
ValueNN
which have dynamic size of columns.
I want to load it to a lookup table
dictionary<string, dictionary<string, string>> lookup_table
so I can get data by
data = lookup_table[key_name][header_name]
Furthermore, I have to write back to csv if data got changed.
How should I create my class and map to read/write it?
csvhelper version = 28.0.1
Except for #dbc comment that the order of the items may change due to the unordered nature of Dictionary<TKey, TValue>, this should work.
void Main()
{
var lookup_table = new Dictionary<string, Dictionary<string, string>>();
using (var reader = new StringReader(",Header1,Header2,Header3\nKey1,value11,value12,value13\nKey2,value21,value22,value23"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Read();
csv.ReadHeader();
var headerLength = csv.Context.Reader.HeaderRecord.Length;
var header = csv.Context.Reader.HeaderRecord;
while (csv.Read())
{
var key = csv.GetField(0);
lookup_table.Add(key, new Dictionary<string, string>());
for (int i = 1; i < headerLength; i++)
{
lookup_table[key][header[i]] = csv.GetField(i);
}
}
}
using (var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
{
var headers = lookup_table.First().Value.Keys.ToList();
csv.WriteField(string.Empty);
foreach (var header in headers)
{
csv.WriteField(header);
}
csv.NextRecord();
foreach (KeyValuePair<string, Dictionary<string, string>> entry in lookup_table)
{
csv.WriteField(entry.Key);
for (int i = 0; i < headers.Count; i++)
{
csv.WriteField(entry.Value[headers[i]]);
}
csv.NextRecord();
}
}
}
I have a map called Statistics and I want to retrieve it's data.
//Reference to the snapshot
DocumentReference docRef = database.Collection("Users").Document("document");
DocumentSnapshot snapshot = await docRef.GetSnapshotAsync();
//Create a variable that sets the document data as a dictionary
Dictionary<string, object> user = snapshot.ToDictionary();
//Create and declare a new variable that will only take the nested dictionary, in this case
//it's called "Statistics"
Dictionary<string, object> statistics = new Dictionary<string, object> { };
statistics = (Dictionary<string, object>)user["Statistics"];
//Read the nested dictionary :)
foreach (var key in statistics)
{
Debug.Log(key.Key + "\t\t" + key.Value);
}
I am new here and actually very new to c#.
In a nutshell, I am using c# via Visual Studio, I am calling a data from a database and I want to save these data in a .csv file. The problem now is that I want to save these data on two columns at the same time.
My code do write them in a file but shifted not on the right rows.
Dictionary<string, string> elementNames = new Dictionary<string, string>();
Dictionary<string, string> elementTypes = new Dictionary<string, string>();
var nodes = webservice.nepService.GetAllElementsOfElementType(webservice.ext, "Busbar", ref elementNames, ref elementTypes);
Dictionary<string, string> nodeResults = new Dictionary<string, string>();
Dictionary<string, string> nodeResults1 = new Dictionary<string, string>();
foreach (var nodename in elementNames.Values)
{
var nodeRes = webservice.nepService.GetResultElementByName(webservice.ext, nodename, "Busbar", -1, "LoadFlow", null);
var Uvolt = GetXMLAttribute(nodeRes, "U");
nodeResults.Add(nodename, Uvolt);
var Upercentage = GetXMLAttribute(nodeRes, "Up");
nodeResults1.Add(nodename, Upercentage);
StringBuilder strBldr = new StringBuilder();
string outputFile = #"C:\Users\12.csv";
string separator = ",";
foreach (var res in nodeResults)
{
strBldr.AppendLine($"{res.Key}{separator}{res.Value}");
}
foreach (var res1 in nodeResults1)
{
strBldr.AppendLine($"{separator}{separator}{res1.Value}");
}
File.WriteAllText(outputFile, strBldr.ToString());
}
this is the output of the previous code:
https://ibb.co/T4trQC3
I want these shifted values to move up beside the other values like that:
https://ibb.co/4S25v0h
Thank you
if you look to the code you are using AppendLine
strBldr.AppendLine($"{separator}{separator}{res1.Value}");
and if you want to append on same line just use Append
strBldr.Append($"{separator}{separator}{res1.Value}");
EDITED:
in linq you can use Zip function to zip to lists
// using System.Linq;
var results = Results.Zip(Results1, (firstList, secondList) => firstList.Key + "," + firstList.Value + "," + secondList.Value);
Edit Full example
public static IDictionary<string, string> Results { get; set; }
public static IDictionary<string, string> Results1 { get; set; }
private static void Main(string[] args)
{
StringBuilder strBldr = new StringBuilder();
string outputFile = #"D:\12.csv";
Results = new Dictionary<string, string>()
{
{"N1", "20"},
{"N2", "0.399992"},
{"N3", "0.369442"},
{"N4", "0.369976"}
};
Results1 = new Dictionary<string, string>()
{
{"N1", "100"},
{"N2", "99.9805"},
{"N3", "92.36053"},
{"N4", "92.49407"}
};
IEnumerable<string> results = Results.Zip(Results1,
(firstList, secondList) => firstList.Key + "," + firstList.Value + "," + secondList.Value);
foreach (string res1 in results)
{
strBldr.AppendLine(res1);
}
File.WriteAllText(outputFile, strBldr.ToString());
}
for faster code you can try this
HashSet<Tuple<string, string, string>> values = new HashSet<Tuple<string, string, string>>();
var nodes = webservice.nepService.GetAllElementsOfElementType(webservice.ext, "Busbar", ref elementNames, ref elementTypes);
foreach (var nodename in elementNames.Values)
{
var nodeRes = webservice.nepService.GetResultElementByName(webservice.ext, nodename, "Busbar", -1, "LoadFlow", null);
var Uvolt = GetXMLAttribute(nodeRes, "U");
var Upercentage = GetXMLAttribute(nodeRes, "Up");
values.Add(Tuple.Create(nodename, Uvolt, Upercentage));
}
var output = string.Join("\n", values.ToList().Select(tuple => $"{tuple.Item1},{tuple.Item2},{tuple.Item3}").ToList());
string outputFile = #"C:\Users\12.csv";
File.WriteAllText(outputFile, output);
if the rowCount for Results and Results1 are same and the keys are in the same order, try:
for (int i = 0; i < Results.Count; i++)
strBldr.AppendLine($"{Results[i].Key}{separator}{Results[i].Value}{separator}{Results1[i].Value}");
Or, if the rows are not in the same order, try:
foreach (var res in Results)
strBldr.AppendLine($"{res.Key}{separator}{res.Value}{separator}{Results1.Single(x => x.Key == res.Key).Value}");
can anyone advise how I should change my code (this is based on section 3.5.1.4.2 from the 3.0 developer manual). I am trying to create multiple nodes via one query in bolt.
using (var driver = GraphDatabase.Driver(Neo4jCredentials.Instance, AuthTokens.Basic(Neo4jCredentials.Username, Neo4jCredentials.Password)))
using (var session = driver.Session())
{
string query = "UNWIND { props } AS map CREATE(n) SET n = map";
Dictionary<string, object> myParameter = new Dictionary<string, object>();
myParameter.Add("props", "{\"props\":[{\"name\":\"Andres\",\"position\":\"Developer\"},{\"name\":\"Michael\",\"position\":\"Developer\"}]}");
return session.Run(query, myParameter);
}
The error I am getting is:
{"Expected map to be a map, but it was :`{\"props\":[{\"name\":\"Andres\",\"position\":\"Developer\"},{\"name\":\"Michael\",\"position\":\"Developer\"}]}`"}
Thanks in advance my learned friends...
Try forming your dictionary of params using an array of dictionaries:
Dictionary<string, object> myParameter = new Dictionary<string, object>();
Dictionary<string, object>[] props =
{
new Dictionary<string, object> {{"name", "Andres"}, {"position", "Developer"}},
new Dictionary<string, object> {{"name", "Michael"}, {"position", "Developer"}}
};
myParameter.Add("props",props);
or with a few less characters:
var myParameter = new Dictionary<string, object>
{
{
"props", new[]
{
new Dictionary<string, string> {{"name", "Andres"}, {"position", "Developer"}},
new Dictionary<string, string> {{"name", "Michael"}, {"position", "Developer"}}
}
}
};
i need read whole resx file in code behind. I did this in this way:
ResXResourceReader rsxrOrganizationSubtypes = new ResXResourceReader(#"D:\DNN_Cafaas\DesktopModules\OPEGIEKA.DNN.Modules.CreateInstitution\App_LocalResources\OrganizationSubtypes.resx");
rsxrOrganizationSubtypes.UseResXDataNodes = true;
IDictionaryEnumerator dict = rsxrOrganizationSubtypes.GetEnumerator();
while (dict.MoveNext())
{
ResXDataNode node = (ResXDataNode)dict.Value;
}
Is there any possibility to sort/order results from resx file ? For example by Name ?
Resolved (sorted by value from resx file). Maybe there is better way to do it, but its working:
ResXResourceReader rsxr = new ResXResourceReader(PathToResX);
rsxr.UseResXDataNodes = true;
IDictionaryEnumerator dictRSXR = rsxr.GetEnumerator();
SortedDictionary<string, string> sortedRSXR = new SortedDictionary<string, string>();
while (dictRSXR.MoveNext())
{
ResXDataNode node = (ResXDataNode)dictRSXR.Value;
sortedRSXR.Add(node.GetValue((ITypeResolutionService)null).ToString(), node.Name);
}
foreach (KeyValuePair<string, string> p in sortedRSXR)
{
counterDDL++;
dropDownList.Items.Insert(counterDDL, new ListItem(p.Key, p.Value));
}
You could add keys and values to a SortedDictionary<string, ResXDataNode> in the while loop. This should sort your entries automatically.