简体   繁体   中英

C# MVC using a CSV file

I have a model that contains some pretty generic properties:

    public class ProductItem
{
    public int      ID { get; set; }
    public string   Description { get; set; }
    public char     Item { get; set; }
    public decimal  Price { get; set; }
    public string   ImagePath { get; set; }
    public string   Barcode { get; set; }
}

I have instances of this model populated from a CSV file using the following:

            DataTable dt = new DataTable();
        dt.Columns.Add("ID", typeof(System.Int32));
        dt.Columns.Add("Description", typeof(System.String));
        dt.Columns.Add("Item", typeof(System.Char));
        dt.Columns.Add("Price", typeof(System.Decimal));
        dt.Columns.Add("ImagePath", typeof(System.String));
        dt.Columns.Add("Barcode", typeof(System.String));

        String[] csv = File.ReadAllLines(csvPath);

        foreach (string csvrow in csv)
        {
            var fields = csvrow.Split(',');
            var row = dt.NewRow();

            row.ItemArray = fields;
            dt.Rows.Add(row);
        }

        return dt;

This returns a Datatable that is then used in the following function to get the list:

        private List<ProductItem> GetAllProductsCSV()
    {
        var filePath = Server.MapPath(@"~/CSV/products.csv");
        var products = new ProductsCSV();
        DataTable results = products.GetProductsFromCSV(filePath);

        List<ProductItem> productItems = (from DataRow dr in results.Rows
                                          select new ProductItem()
                                          {
                                              ID = Convert.ToInt32(dr["ID"]),
                                              Description = dr["Description"].ToString(),
                                              Item = Convert.ToChar(dr["Item"]),
                                              Price = Convert.ToDecimal(dr["Price"]),
                                              ImagePath = dr["ImagePath"].ToString(),
                                              Barcode = dr["Barcode"].ToString(),
                                          }).ToList();

        return productItems;
    }

Firstly, this is all starting to seem a little convoluted for something I think should be a lot easier... Am I making a lot more work for myself than I need to here?

Secondly, I am having a bit of trouble reversing this process when I make changes to a model instance and need to write it back to the CSV file. I understand that I need to re-write the whole lot back in (as I have read that you cant just update 1 row in a CSV)... But if anyone has some examples of how best to achieve this would be greatly appreciated.

I would go directly to a List<ProductItem> instead of loading a DataTable and then convert it to a List.

public List<ProductItem> LoadData(csvPath)
{
    String[] csv = File.ReadAllLines(csvPath);
    List<ProductItem> result = new List<ProducItem>();
    foreach (string csvrow in csv)
    {
        var fields = csvrow.Split(',');
        ProductItem prod = new ProductItem()
        {
            ID = Convert.ToInt32(fields[0]),
            Description = fields[1],
            Item = fields[2][0],
            Price = Convert.ToDecimal(fields[3]),
            ImagePath = fields[4],
            Barcode = fields[5]
        });
        result.Add(prod);
    }
    return result;
}

The inverse process will be a loop over your List and build a proper csv line to write in your file

public void WriteToCsv(string csvPath, List<ProductItem> products)
{
    List<string> lines = new List<string>();
    foreach(ProductItem item in products)
    {
        string line = string.Join(",", item.ID.ToString(), 
                                       item.Description, 
                                       item.Item.ToString(),
                                       item.Price.ToString(), 
                                       item.ImageCode,
                                       item.BarCode);
        lines.Add(line);
   }
   File.WriteAllLines(csvPath, lines);
}

Also keep in mind that this is a very simplicistic way to load an write a CSV file. It is better to use a specialized library for that. A library will handle cases like comma inside the description field or some kind of delimiter between fields

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM