4est
4est

Reputation: 3168

Data has strange format after saved to csv

My data after saved to csv has a format as show in the screenshot:

enter image description here

Here is my C# code.

UserDataDBsDataContext dataContext = new UserDataDBsDataContext();
            List<UserData> usersL = (from u in dataContext.UserDatas
                                         //where u.Id.Equals(13)
                                     select u).ToList();

 StreamWriter writer = new StreamWriter("my_data.txt");
 string csv = String.Join(",", usersL.Select(x => x.ToString()).ToArray());            
 writer.Write(csv);

 writer.Close();

Do you know what is missing or what I made wrong?

UPDATE: UserData.Properties:

enter image description here

Here I'm able to select property by property:

foreach (var i in usersL)
{
    writer.Write(i.Id);               
}

but I want to take whole object, as later then it will be uploaded to my app.

Upvotes: 0

Views: 100

Answers (3)

Mighty Badaboom
Mighty Badaboom

Reputation: 6155

With this code

String.Join(",", usersL.Select(x => x.ToString()).ToArray());   

you are calling the ToString() method from you UserData instances. And per default you'll get the namespace of a class when calling it's ToString() method. If you want to write the data in your csv file you have to get the value from your instances.

One way would be using this code

var lines = usersL.Select(x => string.Format("{0},{1},{2},{3}", x.Id, x.FirstName, x.LastName, x.Type))
                  .ToList();

File.WriteAllLines("my_data.txt", lines);

You can override the ToString() method of your UserData, too. But that is, in my opinion not a clean way because the UserData class should not know something about the way it's saved in a csv file.

/edit: using reflection

var properties = typeof(UserData).GetProperties();
var userValues = new List<string>();

foreach (var user in usersL)
{
    var values = new List<object>();
    foreach (var property in properties)
    {
        object value = property.GetValue(user, null);
        values.Add(value);
    }
    userValues.Add(string.Join(",", values));
}

File.WriteAllLines("my_data.txt", userValues);

Upvotes: 1

Cristian Rusanu
Cristian Rusanu

Reputation: 662

Try using something like this:

Type t = typeof(UserData);
PropertyInfo[] propInfos = t.GetProperties(BindingFlags.Public|BindingFlags.Instance);


using(StreamWriter writer = new StreamWriter("my_data.txt"))
{

    foreach(var user in usersL)
    {

        List<object> propValues = new List<object>();
        foreach(var pi in propInfos)
        {
            propValues.Add(pi.GetValue(user, null));
        }

        string csvLine = String.Join(",", propValues); 

        writer.WriteLine(csvLine);
    }
}

Upvotes: 1

xanatos
xanatos

Reputation: 111870

The default .ToString() of objects in .NET simply writes the full name of the object (so "LayoutMVVM.LinqToSqlClasses.UserData" in your case). You have to overload the .ToString() or manually compose your data. Note that writing directly a CSV is ripe to problems... Escaping a CSV is complex (escaping This is a "quoted" string for example, or new lines). Search for a library that does it correctly.

Upvotes: 1

Related Questions