I am trying to export data from a list of object to a csv file. I managed to create the file and create the first row, however I need to create some kind of for each loop to loop through each object.
This is my code:
string pathDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = pathDesktop + "\\mycsvfile.csv";
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
string delimter = ",";
string[][] output = new string[][] {
new string[] {"TEST1","TEST2"}
};
int length = output.GetLength(0);
StringBuilder sb = new StringBuilder();
for (int index = 0; index < length; index++)
{
sb.AppendLine(string.Join(delimter, output[index]));
File.AppendAllText(filePath, sb.ToString());
}
Is there any way to create this file and using a loop to loop through all my objects and display them in file.
Here's the solution:
string pathDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = pathDesktop + "\\mycsvfile.csv";
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
string delimter = ",";
List<string[]> output = new List<string[]>();
//flexible part ... add as many object as you want based on your app logic
output.Add(new string[] {"TEST1","TEST2"});
output.Add(new string[] {"TEST3","TEST4"});
int length = output.Count;
using (System.IO.TextWriter writer = File.CreateText(filePath))
{
for (int index = 0; index < length; index++)
{
writer.WriteLine(string.Join(delimter, output[index]));
}
}
Assuming that obj is a List of String I usually use this
System.IO.File.WriteAllLines(stringFilePath, obj.ToArray());
If you want a generic extension that will loop through every item in your list adding it to a new line and loop through every public property with a getter and create a comma separated list of fields per property on the line you can use my extension as per my tip, here or my Gist, here, calling the extension on the List like so:
MyList.ToDelimitedText(",", true);
Full code below
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Gists.Extensions.ListOfTExtentions
{
public static class ListOfTExtentions
{
/// <summary>
/// Converst this instance to delimited text.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="instance">The instance.</param>
/// <param name="delimiter">The delimiter.</param>
/// <param name="trimTrailingNewLineIfExists">
/// If set to <c>true</c> then trim trailing new line if it exists.
/// </param>
/// <returns></returns>
public static string ToDelimitedText<T>(this List<T> instance,
string delimiter,
bool trimTrailingNewLineIfExists = false)
where T : class, new()
{
int itemCount = instance.Count;
if (itemCount == 0) return string.Empty;
var properties = GetPropertiesOfType<T>();
int propertyCount = properties.Length;
var outputBuilder = new StringBuilder();
for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
{
T listItem = instance[itemIndex];
AppendListItemToOutputBuilder(outputBuilder, listItem, properties, propertyCount, delimiter);
AddNewLineIfRequired(trimTrailingNewLineIfExists, itemIndex, itemCount, outputBuilder);
}
var output = TrimTrailingNewLineIfExistsAndRequired(outputBuilder.ToString(), trimTrailingNewLineIfExists);
return output;
}
private static void AddDelimiterIfRequired(StringBuilder outputBuilder, int propertyCount, string delimiter,
int propertyIndex)
{
bool isLastProperty = (propertyIndex + 1 == propertyCount);
if (!isLastProperty)
{
outputBuilder.Append(delimiter);
}
}
private static void AddNewLineIfRequired(bool trimTrailingNewLineIfExists, int itemIndex, int itemCount,
StringBuilder outputBuilder)
{
bool isLastItem = (itemIndex + 1 == itemCount);
if (!isLastItem || !trimTrailingNewLineIfExists)
{
outputBuilder.Append(Environment.NewLine);
}
}
private static void AppendListItemToOutputBuilder<T>(StringBuilder outputBuilder,
T listItem,
PropertyInfo[] properties,
int propertyCount,
string delimiter)
where T : class, new()
{
for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex += 1)
{
var property = properties[propertyIndex];
var propertyValue = property.GetValue(listItem);
outputBuilder.Append(propertyValue);
AddDelimiterIfRequired(outputBuilder, propertyCount, delimiter, propertyIndex);
}
}
private static PropertyInfo[] GetPropertiesOfType<T>() where T : class, new()
{
Type itemType = typeof (T);
var properties = itemType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public);
return properties;
}
private static string TrimTrailingNewLineIfExistsAndRequired(string output, bool trimTrailingNewLineIfExists)
{
if (!trimTrailingNewLineIfExists || !output.EndsWith(Environment.NewLine)) return output;
int outputLength = output.Length;
int newLineLength = Environment.NewLine.Length;
int startIndex = outputLength - newLineLength;
output = output.Substring(startIndex, newLineLength);
return output;
}
}
}
Examples of calling the code can be found in these tests:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Gists.Extensions.ListOfTExtentions;
namespace Gists_Tests.ExtensionTests.ListOfTExtentionTests
{
[TestClass]
public class ListOfT_ToDelimitedTextTests
{
#region Mock Data
private class SimpleObject
{
public int Id { get; set; }
}
private class ComplextObject : SimpleObject
{
public string Name { get; set; }
public bool Active { get; set; }
}
#endregion
#region Tests
[TestMethod]
public void ToDelimitedText_ReturnsCorrectNumberOfRows()
{
// ARRANGE
var itemList = new List<ComplextObject>
{
new ComplextObject {Id = 1, Name = "Sid", Active = true},
new ComplextObject {Id = 2, Name = "James", Active = false},
new ComplextObject {Id = 3, Name = "Ted", Active = true},
};
const string delimiter = ",";
const int expectedRowCount = 3;
const bool trimTrailingNewLineIfExists = true;
// ACT
string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
var lines = result.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var actualRowCount = lines.Length;
// ASSERT
Assert.AreEqual(expectedRowCount, actualRowCount);
}
[TestMethod]
public void ToDelimitedText_ReturnsCorrectNumberOfProperties()
{
// ARRANGE
var itemList = new List<ComplextObject>
{
new ComplextObject {Id = 1, Name = "Sid", Active = true}
};
const string delimiter = ",";
const int expectedPropertyCount = 3;
// ACT
string result = itemList.ToDelimitedText(delimiter);
var lines = result.Split(Environment.NewLine.ToCharArray());
var properties = lines.First().Split(delimiter.ToCharArray());
var actualPropertyCount = properties.Length;
// ASSERT
Assert.AreEqual(expectedPropertyCount, actualPropertyCount);
}
[TestMethod]
public void ToDelimitedText_RemovesTrailingNewLine_WhenSet()
{
// ARRANGE
var itemList = new List<ComplextObject>
{
new ComplextObject {Id = 1, Name = "Sid", Active = true},
new ComplextObject {Id = 2, Name = "James", Active = false},
new ComplextObject {Id = 3, Name = "Ted", Active = true},
};
const string delimiter = ",";
const bool trimTrailingNewLineIfExists = true;
// ACT
string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
bool endsWithNewLine = result.EndsWith(Environment.NewLine);
// ASSERT
Assert.IsFalse(endsWithNewLine);
}
[TestMethod]
public void ToDelimitedText_IncludesTrailingNewLine_WhenNotSet()
{
// ARRANGE
var itemList = new List<ComplextObject>
{
new ComplextObject {Id = 1, Name = "Sid", Active = true},
new ComplextObject {Id = 2, Name = "James", Active = false},
new ComplextObject {Id = 3, Name = "Ted", Active = true},
};
const string delimiter = ",";
const bool trimTrailingNewLineIfExists = false;
// ACT
string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
bool endsWithNewLine = result.EndsWith(Environment.NewLine);
// ASSERT
Assert.IsTrue(endsWithNewLine);
}
#endregion
}
}
Pass each string array collection to this function and this will return a CSV formatted string that you can either save to a large string buffer or write line by line to a file.
C#
public string CSVout(string[] strArray)
{
string sOut = "";
foreach (void s_loopVariable in strArray) {
s = s_loopVariable;
if (s.Contains(","))
s = Strings.Chr(34) + s + Strings.Chr(34);
sOut += s + ",";
}
if (Strings.Right(sOut, 1) == ",")
sOut = Strings.Left(#out, #out.Length - 1);
return sOut;
}
VB.NET:
Function CSVout(strArray() As String) As String
Dim out As String = ""
For Each s In strArray
If s.Contains(",") Then s = Chr(34) + s + Chr(34)
out &= s + ","
Next
If Strings.Right(out, 1) = "," Then out = Strings.Left(out, out.Length - 1)
Return out
End Function
Related
passing a string like this to the code behind:
0,-1|1,-1|2,-1|3,-1|4,-1|5,-1|6,-1|7,-1|8,-1
I need to be able to asign the values before and after the "," symbol per each "|" symbol that exits in the string, into separated variables, "line" for first value (before the ",") and "group" for the next one (after the ",").
Right now I'm trying with this, but I'm having some issues with converting from string[] to string.
public static string GuardarGrupos(string parametro){
var data = parametro.Split(Convert.ToChar("|"));
var datos = "";
string[] linea;
var grupo = "";
//Iterate through each of the letters
foreach (var check in data)
{
datos = data[0];
linea = data[0].Split(Convert.ToChar(","));
}
return linea;
}
Any Idea how can I achieve this?
Make a class or struct to hold your values:
public class DataObject
{
public string X {get; set;}
public string Y {get; set;}
}
Return a List<T> of type DataObject
public static List<DataObject> GuardarGrupos(string parametro){
//List to return
List<DataObject> returnList = new List<DataObject>();
//Split the string on pipe to get each set of values
var data = parametro.Split('|'); //No need to do a convert.char(),
//String.Split has an overload that takes a character, use single quotes for character
//Iterate through each of the letters
foreach (var check in data)
{
//Split on comma to get the individual values
string[] values = check.Split(',');
DataObject do = new DataObject()
{
X = values[0];
Y = values[1];
};
returnList.Add(do);
}
return returnList;
}
Once you have the List<DataObject>, you can form line and group using linq and string.Join:
List<DataObject> myList = GuardarGrupos("0,-1|1,-1|2,-1|3,-1|4,-1|5,-1|6,-1|7,-1|8,-1");
string line = string.Join(",", myList.Select(x => x.X);
string group = string.Join(",", myList.Select(y => y.Y);
Instead of using local variables , create a Class that stores your retrieved values. then in the main you could handle/manipulate those values as required.
public class MyData
{
public string Datos { get; set; }
public string Linea { get; set; }
public string Grupo { get; set; }
}
public static List<MyData> myFunction(string parametro)
{
List<MyData> result = new List<MyData>();
var data = parametro.Split(Convert.ToChar("|"));
foreach (var check in data)
{
MyData temp = new MyData();
var line = check.Split(',');
temp.Datos = line[0];
temp.Linea = line[1];
temp.Grupo = check;
result.Add(temp);
}
return result;
}
static void Main(string[] args)
{
var t = myFunction("0,-1|1,-1|2,-1|3,-1|4,-1|5,-1|6,-1|7,-1|8,-1");
}
Here is a robust solution that's just a simple iteration over a string.
void Main()
{
var xs = "0,-1|1,-1|2,-1|3,-1|4,-1|5,-1|6,-1|7,-1|8,-1";
var stack = new Stack<Pair>();
stack.Push(new Pair());
foreach(var x in xs)
if(x == '|')
stack.Push(new UserQuery.Pair());
else
stack.Peek().Accept(x);
foreach (var x in stack.Reverse())
Console.WriteLine(x);
}
sealed class Pair
{
Action<char> _Accept;
readonly List<char> Line = new List<char>();
readonly List<char> Group = new List<char>();
public Pair()
{
_Accept = x => Line.Add(x);
}
public void Accept(char c)
{
if(c == ',')
_Accept = x => Group.Add(x);
else
_Accept(c);
}
public override string ToString()
{
return "Line:" + new string(Line.ToArray()) + " Group:" + new string(Group.ToArray());
}
}
I have populated a treeview using this code:
private void updateTree()
{
treeView1.Nodes.Clear();
List<TreeNode> graphicsNodes = new List<TreeNode>();
foreach (Graphic graphic in graphics)
{
List<TreeNode> templateNodes = new List<TreeNode>();
foreach (Template template in graphic.templates)
{
List<TreeNode> aliasNodes = new List<TreeNode>();
foreach(Alias alias in template.aliases)
{
aliasNodes.Add(new TreeNode(alias.aliasName + ": " + alias.aliasValue));
}
templateNodes.Add(new TreeNode(template.templateName, aliasNodes.ToArray()));
}
graphicsNodes.Add(new TreeNode(graphic.fileName.Replace(".g", ""), templateNodes.ToArray()));
}
treeView1.Nodes.Add(new TreeNode("Graphics", graphicsNodes.ToArray()));
}
After manipulating, renaming and deleting some of these elements in the TreeView, is it possible to rebuild my Grapics structure with the new values?
This structure is built so that each Graphic has many Templates and each Template has many Aliases, this code is defined as follows:
public class Graphic
{
public string filePath;
public string fileName;
public List<Template> templates;
public Graphic(List<Template> _templates, string fpath, string fName)
{
templates = _templates;
fileName = fName;
filePath = fpath;
}
}
public class Template
{
public List<Alias> aliases;
public string templateName;
public Template(string instString, string userdataString)
{
templateName = (instString.Replace("inst ", "").Replace(" 0 0", "")).Replace(" ","");
aliases = new List<Alias>();
string[] aliasStrings = userdataString.Replace("\"","").Split(new string[1] { "text_alias" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string segment in aliasStrings)
{
if (segment.Contains("userdata")) { continue; }
string aliasString = "text_alias" + segment;
string[] sections = aliasString.Split('^');
aliases.Add(new Alias(sections[0].Replace("text_alias=", ""), (sections[1].Replace("text_exp_flag=", "") == "1"), sections[2].Replace("alias_new_name=", ""), sections[3].Replace("alias_value=", ""))); //Sorry!
}
}
}
public class Alias
{
public string aliasName;
public string aliasValue;
public string newName;
public bool expectedFlag;
public Alias(string name, bool expected, string nName, string value)
{
aliasName = name;
aliasValue = value;
newName = nName;
expectedFlag = expected;
}
}
If this is not easily achievable, what would be the best way to approach this from a different angle?
Thanks in advance!
Try this,
for (int i = 0; i <= dst.Tables[0].Rows.Count - 1; i++)
{
nodeTables.Nodes.Add(dst.Tables[0].Rows[i]["SchemaName"].ToString() + "." + dst.Tables[0].Rows[i]["TableName"].ToString());
nodeTables.Nodes[i].ImageIndex = 2;
nodeTables.Nodes[i].Nodes.Add("Columns");
//Filling the Column Names
DataSet dstCol = new DataSet();
dstCol = common.GetColumns(Convert.ToInt32(dst.Tables[0].Rows[i]["object_Id"]));
for (int col = 0; col <= dstCol.Tables[0].Rows.Count - 1; col++)
{
nodeTables.Nodes[i].Nodes[0].ImageIndex = 0;
nodeTables.Nodes[i].Nodes[0].Nodes.Add(dstCol.Tables[0].Rows[col]["name"].ToString());
nodeTables.Nodes[i].Nodes[0].Nodes[col].ImageIndex = 1;
}
}
I am working my way through a C# course so this question is more academic than real world.
I want to search for string in an array of classes that includes one or more subsidiary (embedded)array of classes. I want to be able to search both the parent and the subsidiary arrays. I've been trying the NET Framework Class Library Array Methods but am getting nowhere - you'll see my Array.IndexOf returns -1. I've pasted my code below and would be grateful for any advice. I know there are more sophisticated ways to do this but I need to stick with arrays for the time being. Thanks in advance.
using System;
namespace Nested_Arrays
{
public class Program
{
static void Main(string[] args)
{
Student[] StudentArray = new Student[3];
StudentSubjects[] StudentSubjectsArray = new StudentSubjects[3];
StudentArray[0] = new Student() {
StudentName = "Peter", StudentLocation = "Australia"
};
StudentArray[0].StudentSubjectsArray[0] = new StudentSubjects() {
SubjectName = "Calculus", StudentsResult = "Pass"
};
StudentArray[0].StudentSubjectsArray[1] = new StudentSubjects() {
SubjectName = "Algebra", StudentsResult = "Pass"
};
StudentArray[0].StudentSubjectsArray[2] = new StudentSubjects() {
SubjectName = "Statistics", StudentsResult = "Pass"
};
StudentArray[1] = new Student() {
StudentName = "Michelle", StudentLocation = "France"
};
StudentArray[1].StudentSubjectsArray[0] = new StudentSubjects() {
SubjectName = "Engineering", StudentsResult = "Pass"
};
StudentArray[1].StudentSubjectsArray[1] = new StudentSubjects() {
SubjectName = "Algebra", StudentsResult = "Pass"
};
StudentArray[1].StudentSubjectsArray[2] = new StudentSubjects() {
SubjectName = "Aramaic", StudentsResult = "Pass"
};
StudentArray[2] = new Student() {
StudentName = "Mitchell", StudentLocation = "Canada"
};
StudentArray[2].StudentSubjectsArray[0] = new StudentSubjects() {
SubjectName = "Engineering", StudentsResult = "Pass"
};
StudentArray[2].StudentSubjectsArray[1] = new StudentSubjects() {
SubjectName = "Greek", StudentsResult = "Pass"
};
StudentArray[2].StudentSubjectsArray[2] = new StudentSubjects() {
SubjectName = "Aramaic", StudentsResult = "Pass"
};
for (int i = 0; i < 3; i++)
{
Console.WriteLine($ "\n{i + 1,3} {StudentArray[i].StudentName,-10} {StudentArray[i].StudentLocation,-15}");
for (int j = 0; j < 3; j++) {
Console.WriteLine($ "{j + 1,6} {StudentArray[i].StudentSubjectsArray[j].SubjectName,-15} {StudentArray[i].StudentSubjectsArray[j].StudentsResult,-10}");
}
}
String searchString = "Mitchell";
Console.WriteLine($ "\n We are searching for \"{searchString}\"");
int index = Array.IndexOf(StudentArray, searchString);
Console.WriteLine(" The first occurrence of \"{0}\" is at index {1}.", searchString, index);
searchString = "Aramaic";
Console.WriteLine($ "\n We are searching for \"{searchString}\"");
index = Array.IndexOf(StudentSubjectsArray, searchString);
Console.WriteLine(" The first occurrence of \"{0}\" is at index {1}.", searchString, index);
Console.WriteLine($ "\n");
}
public class Student
{
private string studentName;
public string StudentName {
get {
return studentName;
}
set {
studentName = value;
}
}
private string studentLocation;
public string StudentLocation {
get {
return studentLocation;
}
set {
studentLocation = value;
}
}
private StudentSubjects[] studentSubjectsArray = new StudentSubjects[3];
public StudentSubjects[] StudentSubjectsArray {
get {
return studentSubjectsArray;
}
set {
studentSubjectsArray = value;
}
}
//Constructor
public Student() {}
}
public class StudentSubjects {
private string subjectName;
public string SubjectName {
get {
return subjectName;
}
set {
subjectName = value;
}
}
private string studentsResult;
public string StudentsResult {
get {
return studentsResult;
}
set {
studentsResult = value;
}
}
//Constructor
public StudentSubjects() {}
}
}
}
Array.IndexOf searches for the specified object and returns the index of its first occurrence in a one-dimensional array.
In your case you need to search for object properties and find an index of matched object. I suggest use use Linq to search for an object that matches property value and then search for an index of an object (as follows).
var item = StudentArray.FirstOrDefault(x=> x.StudentName.Equals(searchString, StringComparison.CurrentCultureIgnoreCase)
|| x.StudentSubjectsArray.Any(s=>s.SubjectName.Equals(searchString, StringComparison.CurrentCultureIgnoreCase)));
if(item!= null)
index = Array.IndexOf(StudentArray, item);
Check this working demo
I think that I've finally did it , it took me a wile, because i'm a novice..
So,
1) first off all I added two lists of strings in each Class
like:
public class StudentSubjects
{
public List<String> studentsubjectlist = new List<string>();
and
public class StudentSubjects
{
public List<String> studentsubjectlist = new List<string>();
then you will need to add all your propertys to those lists, by using "Set" accessor of the property:
public string StudentName
{
get
{
return studentName;
}
set
{
studentName = value;
studentslist.Add(value);
}
}
If you do debugging in this stage you will see there is a list in every object in the array, that contains all the propertys of the Object.
2) Your index has to be an Array because it will contain more then one number:
int[] index = new int[StudentArray.Length];
3) Now we can loop.
int i;
int j;
int x;
for ( i = 0; i < StudentArray.Length; i++)
{
for ( j = 0; j < StudentArray[i].studentslist.Count; j++)
{
if (StudentArray[i].studentslist[j] == searchString)
{
index[0] = i;
index[1] = -1;
index[2] = j;
break;
}
}
for ( x = 0, j = 0; j < StudentArray[i].StudentSubjectsArray[x].studentsubjectlist.Count; j++)
{
if (StudentArray[i].StudentSubjectsArray[x].studentsubjectlist[j] == searchString)
{
index[0] = i;
index[1] = x;
index[2] = j;
break;
}
else if (j == StudentArray[i].StudentSubjectsArray [x].studentsubjectlist.Count)
{
x++;
j = 0;
}
}
}
4)Pay attention that:
int i is a index of the Student in the Array,
int x is a index of the StudentSubject, if searchword is inside of Student object and not inside StudentSubject, x will return -1.
int j is a index of property inside of List.
5) You will also need to change your Console.Writeline to:
Console.WriteLine( "\n We are searching for \"{searchString}\"");
Console.WriteLine(" The first occurrence of \"{0}\" is at index {1}.{2}. {3}.", searchString, index[0], index[1], index[2]);
I've been stuck trying to get the CSV Helper to write to a file. When I run DownloadRegistrantsCsv it downloads the file with the proper name and everything else, but it never writes anything to it.
public async Task<Stream> GetDownloadStreamAsync(int id)
{
var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream);
var streamReader = new StreamReader(memoryStream);
var csvHelper = new CsvHelper.CsvWriter(streamWriter);
csvHelper.WriteRecord(new EventRegistrant { FirstName = "Max" });
await memoryStream.FlushAsync();
memoryStream.Position = 0;
return memoryStream;
}
public async Task<ActionResult> DownloadRegistrantsCsv(int id)
{
var #event = await _service.GetAsync(id, true);
if (#event == null)
return HttpNotFound();
var stream = await _service.GetDownloadStreamAsync(id);
return File(stream, "application/txt", "test" + ".csv");
}
I've also tried just using the documentation for the CSV Helper and I can't even get that to write. Here's what I've got for that...
// Copyright 2009-2015 Josh Close and Contributors
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
// http://csvhelper.com
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Web.Script.Serialization;
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;
namespace CsvHelper.Example
{
class Program
{
private const string columnSeparator = ":";
static void Main(string[] args)
{
//ReadRawFieldsByIndex();
//ReadRawFieldsByName();
//ReadFieldsByIndex();
//ReadRecordsNoAttributes();
//ReadRecordsWithAttributes();
//ReadAllRecords();
//WriteRawFields();
//WriteFields();
WriteRecordsNoAttributes();
//WriteRecordsWithAttributes();
WriteAllRecords();
Console.ReadKey();
}
public static void ReadRawFieldsByIndex()
{
Console.WriteLine("Raw fields by index:");
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, true))))
{
while (reader.Read())
{
Console.Write(reader.GetField(0) + columnSeparator);
Console.Write(reader.GetField(1) + columnSeparator);
Console.Write(reader.GetField(2) + columnSeparator);
Console.WriteLine(reader.GetField(3));
}
}
Console.WriteLine();
}
public static void ReadRawFieldsByName()
{
Console.WriteLine("Raw fields by name:");
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, true))))
{
while (reader.Read())
{
Console.Write(reader.GetField("String Column") + columnSeparator);
Console.Write(reader.GetField("Int Column") + columnSeparator);
Console.Write(reader.GetField("Guid Column") + columnSeparator);
Console.Write(reader.GetField("Does Not Exist Column") + columnSeparator);
Console.WriteLine(reader.GetField("Custom Type Column"));
}
}
Console.WriteLine();
}
public static void ReadFieldsByIndex()
{
Console.WriteLine("Fields by index:");
var customTypeTypeConverter = new CustomTypeTypeConverter();
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, true))))
{
while (reader.Read())
{
Console.Write(reader.GetField<string>(0) + columnSeparator);
Console.Write(reader.GetField<int>("Int Column") + columnSeparator);
Console.Write(reader.GetField<Guid>(2) + columnSeparator);
Console.WriteLine(reader.GetField<CustomType>(3, customTypeTypeConverter));
}
}
Console.WriteLine();
}
public static void ReadRecordsNoAttributes()
{
Console.WriteLine("Records no attributes:");
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, false))))
{
while (reader.Read())
{
Console.WriteLine(reader.GetRecord<CustomObject>());
}
}
Console.WriteLine();
}
public static void ReadRecordsWithAttributes()
{
Console.WriteLine("Records with attributes:");
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, true))))
{
reader.Configuration.RegisterClassMap<CustomObjectWithMappingMap>();
while (reader.Read())
{
Console.WriteLine(reader.GetRecord<CustomObjectWithMapping>());
}
}
Console.WriteLine();
}
public static void ReadAllRecords()
{
Console.WriteLine("All records:");
using (var reader = new CsvReader(new StreamReader(GetDataStream(true, false))))
{
var records = reader.GetRecords<CustomObject>();
foreach (var record in records)
{
Console.WriteLine(record);
}
}
Console.WriteLine();
}
public static void WriteRawFields()
{
Console.WriteLine("Write raw fields");
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
using (var writer = new CsvWriter(streamWriter))
{
writer.WriteField("String Column");
writer.WriteField("Int Column");
writer.WriteField("Guid Column");
writer.WriteField("Custom Type Column");
writer.NextRecord();
writer.WriteField("one");
writer.WriteField((1).ToString());
writer.WriteField(Guid.NewGuid().ToString());
writer.WriteField((new CustomType { First = 1, Second = 2, Third = 3 }).ToString());
writer.NextRecord();
memoryStream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}
Console.WriteLine();
}
public static void WriteFields()
{
Console.WriteLine("Write fields");
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
using (var writer = new CsvWriter(streamWriter))
{
writer.WriteField("String Column");
writer.WriteField("Int Column");
writer.WriteField("Guid Column");
writer.WriteField("Custom Type Column");
writer.NextRecord();
writer.WriteField("one");
writer.WriteField(1);
writer.WriteField(Guid.NewGuid());
writer.WriteField(new CustomType { First = 1, Second = 2, Third = 3 });
writer.NextRecord();
memoryStream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}
Console.WriteLine();
}
public static void WriteRecordsNoAttributes()
{
Console.WriteLine("Write records no attributes:");
var records = new List<CustomObject>
{
new CustomObject
{
CustomTypeColumn = new CustomType
{
First = 1,
Second = 2,
Third = 3,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 1,
StringColumn = "one",
},
new CustomObject
{
CustomTypeColumn = new CustomType
{
First = 4,
Second = 5,
Third = 6,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 2,
StringColumn = "two",
},
};
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
using (var writer = new CsvWriter(streamWriter))
{
foreach (var record in records)
{
writer.WriteRecord(record);
}
memoryStream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}
Console.WriteLine();
}
public static void WriteRecordsWithAttributes()
{
Console.WriteLine("Write records with attributes:");
var records = new List<CustomObjectWithMapping>
{
new CustomObjectWithMapping
{
CustomTypeColumn = new CustomType
{
First = 1,
Second = 2,
Third = 3,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 1,
StringColumn = "one",
},
new CustomObjectWithMapping
{
CustomTypeColumn = new CustomType
{
First = 4,
Second = 5,
Third = 6,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 2,
StringColumn = "two",
},
};
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
using (var writer = new CsvWriter(streamWriter))
{
foreach (var record in records)
{
writer.WriteRecord(record);
}
memoryStream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}
Console.WriteLine();
}
public static void WriteAllRecords()
{
Console.WriteLine("Write all records with attributes:");
var records = new List<CustomObjectWithMapping>
{
new CustomObjectWithMapping
{
CustomTypeColumn = new CustomType
{
First = 1,
Second = 2,
Third = 3,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 1,
StringColumn = "one",
},
new CustomObjectWithMapping
{
CustomTypeColumn = new CustomType
{
First = 4,
Second = 5,
Third = 6,
},
GuidColumn = Guid.NewGuid(),
IntColumn = 2,
StringColumn = "two",
},
};
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
using (var writer = new CsvWriter(streamWriter))
{
writer.Configuration.RegisterClassMap<CustomObjectWithMappingMap>();
writer.WriteRecords(records as IEnumerable);
memoryStream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}
Console.WriteLine();
}
public static MemoryStream GetDataStream(bool hasHeader, bool hasSpacesInHeaderNames)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
if (hasHeader)
{
var header = hasSpacesInHeaderNames
? "String Column,Int Column,Guid Column,Custom Type Column"
: "StringColumn,IntColumn,GuidColumn,CustomTypeColumn";
writer.WriteLine(header);
}
writer.WriteLine("one,1,{0},1|2|3", Guid.NewGuid());
writer.WriteLine("two,2,{0},4|5|6", Guid.NewGuid());
writer.WriteLine("\"this, has a comma\",2,{0},7|8|9", Guid.NewGuid());
writer.WriteLine("\"this has \"\"'s\",4,{0},10|11|12", Guid.NewGuid());
writer.Flush();
stream.Position = 0;
return stream;
}
public class CustomType
{
public int First { get; set; }
public int Second { get; set; }
public int Third { get; set; }
public override string ToString()
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(this);
}
}
public class CustomTypeTypeConverter : ITypeConverter
{
public string ConvertToString(TypeConverterOptions options, object value)
{
var obj = (CustomType)value;
return string.Format("{0}|{1}|{2}", obj.First, obj.Second, obj.Third);
}
public object ConvertFromString(TypeConverterOptions options, string text)
{
var values = ((string)text).Split('|');
var obj = new CustomType
{
First = int.Parse(values[0]),
Second = int.Parse(values[1]),
Third = int.Parse(values[2]),
};
return obj;
}
public bool CanConvertFrom(Type type)
{
throw new NotImplementedException();
}
public bool CanConvertTo(Type type)
{
throw new NotImplementedException();
}
}
public class CustomObject
{
public CustomType CustomTypeColumn { get; set; }
public Guid GuidColumn { get; set; }
public int IntColumn { get; set; }
public string StringColumn { get; set; }
public override string ToString()
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(this);
}
}
public class CustomObjectWithMapping
{
public CustomType CustomTypeColumn { get; set; }
public Guid GuidColumn { get; set; }
public int IntColumn { get; set; }
public string StringColumn { get; set; }
public string IgnoredColumn { get; set; }
//public override string ToString()
//{
// var serializer = new JavaScriptSerializer();
// return serializer.Serialize(this);
//}
}
public sealed class CustomObjectWithMappingMap : CsvClassMap<CustomObjectWithMapping>
{
public CustomObjectWithMappingMap()
{
Map(m => m.CustomTypeColumn).Name("Custom Type Column").Index(3).TypeConverter<CustomTypeTypeConverter>();
Map(m => m.GuidColumn).Name("Guid Column").Index(2);
Map(m => m.IntColumn).Name("Int Column").Index(1);
Map(m => m.StringColumn).Name("String Column").Index(0);
}
}
}
}
Can anyone point me to what I might be missing or doing wrong?
If you have a DataTable you can convert it to a Comma Separated Value list of strings like this...
/// <summary>
/// Creates a comma separated value string from a datatable.
/// </summary>
public static string ToCSV(DataTable table)
{
StringBuilder csv = new StringBuilder();
for(int i = 0; i < table.Columns.Count ;i++) // process the column headers
{
if (i > 0)
csv.Append(",");
csv.Append(_FormatToCSVField(table.Columns[i].ColumnName));
}
if (table.Columns.Count > 0)
csv.Append("\r\n");
for (int i = 0; i < table.Rows.Count; i++) // process the row data
{
for (int j = 0; j < table.Columns.Count; j++) // process each field in the data row.
{
if (j > 0)
csv.Append(",");
csv.Append(_FormatToCSVField(table.Rows[i][j].ToString()));
}
csv.Append("\r\n");
}
return csv.ToString();
}
private static string _FormatToCSVField(string unformattedField)
{
return "\"" + unformattedField.Replace("\"", "\"\"") + "\"";
}
Or if you didn't have a DataTable; take take your created comma separated value (CSV) list of string "row1 column 1, row1 column2, row1 column3, \r\n, row2, colum1... etc..."
and save it to a CSV File, like this...
//Your CSV String
string WhatToWrite = "row1 column 1, row1 column2, row1 column3, \r\n";
//Convert your CSV String to byte[]
byte[] PutWhatToWriteIntoBytes = Encoding.GetEncoding("iso-8859-1").GetBytes(WhatToWrite);
//Write the byte[] to CSV readable by excel
string filename = "WhatYouWantToCallYourFile" + ".csv";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", filename.ToString());
Response.Clear();
Response.BinaryWrite(PutWhatToWriteIntoBytes);
Response.End();
Its really hard to follow all your code. What exactly is it that you are trying to write to a CSV...Get that; check if it is good. then write to the file. determine if you are writing an empty string, or if the writing is losing the string
Flushing the stream writer worked for me if you still want to use the CSV Helper
i'm new on the world of elasticsearch and i'm trying to code it in c# with the NEST aPI.
I succed to index some doc with content but when i try to search, the research take ~4sec.
I use visual studio 2012
I hope you can help me :)
[ElasticType(Name = "document")]
public class Document
{
public int Id { get; set; }
[ElasticProperty(Store = true)]
public string Titre { get; set; }
[ElasticProperty(Type = FieldType.Attachment, TermVector = TermVectorOption.WithPositionsOffsets, Store = true)]
public Attachment File { get; set; }
}
public class Attachment
{
[ElasticProperty(Name = "_content")]
public string Content { get; set; }
[ElasticProperty(Name = "_content_type")]
public string ContentType { get; set; }
[ElasticProperty(Name = "_name")]
public string Name { get; set; }
}
static int i = 0;
static int j = 0;
This is my class's declarations
static void Main(string[] args)
{
//New connection
//var node = new Uri("http://serv-intra:9200");
var node = new Uri("http://localhost:9200/");
var settings = new ConnectionSettings(
node,
defaultIndex: "document"
);
var client = new ElasticClient(settings);
//Creation of my index with mapping
//client.CreateIndex("document", c => c
// .AddMapping<Document>(m => m.MapFromAttributes())
// );
//function for index
//feignasse(client);
var query = Query<Document>.Term("_all", "chu");
var searchResults = client.Search<Document>(s => s
.From(0)
.Size(200)
.Query(query)
);
}
protected static void feignasse(ElasticClient client)
{
// Create new stopwatch
Stopwatch stopwatch = new Stopwatch();
// Begin timing
stopwatch.Start();
Indexation(#"\\serv-intra\Documents", client);
// Stop timing
stopwatch.Stop();
}
//This is my function for index
protected static void Indexation(string path, ElasticClient client)
{
string[] rootDirectories = Directory.GetDirectories(path);
string[] rootFiles = Directory.GetFiles(path);
foreach (string nomfich in rootFiles)
{
if (nomfich.Length < 256)
{
FileInfo file = new FileInfo(nomfich);
var attachement = new Attachment();
attachement.Content = Convert.ToBase64String(File.ReadAllBytes(nomfich));
attachement.Name = file.Name;
attachement.ContentType = GetMimeType(file.Extension);
var document = new Document
{
Id = i,
Titre = file.Name,
File = attachement,
};
var index = client.Index(document);
i++;
}
else
{
j++;
}
}
foreach (string newPath in rootDirectories)
{
Indexation(newPath, client);
}
So i explain you, in my server i have a sharing of doc, and i just travel him in order to catch all my doc and index then in elasticsearch
I have to node with 0 replica and 5 shards
Thanks you