i've just got a routine working that uploads a CSV file from a client Internet Browser to a server directory. Then the file is read into a String array with :
public HttpResponseMessage Upload()
{
    HttpPostedFile file = HttpContext.Current.Request.Files[0];
    var path = Path.Combine(
        HttpContext.Current.Server.MapPath("~/App_Data/uploads"), 
        file.FileName   );
    string[] Lines = System.IO.File.ReadAllLines(path);
    ReadCsv(Lines,file.FileName ); //......ETCETC
This all works great, however my issue is the speed. I know the problem I have is that I am looping through each record in the Array and inserting into my Model. My question is, how can I perform this faster. I have say 19,000 rows and its a 90 minute process. The file upload takes 10 seconds for 20MB. All fine, I need to alter this procedure called UploadCSV() to perhaps copy the records in say a LINQ SQL Statement, that would mean no LOOPING. Does anyone have any ideas how to do this? Here is my 'slow procedure' thats looping each record. I need to go faster from the Array to the Database, perhaps in one step:
public void UploadCSV(String[] Lines, string filename)
{
    string[] Fields;
    Fields = Lines[0].Split(new char[] { '|' });
    int Cols = Fields.GetLength(0);
    for (int i = 1; i < Lines.GetLength(0); i++)
    {
        Fields = Lines[i].Split(new char[] { '|' });
        Water water = new Water()
        {
            SupplyPointId = decimal.Parse(Fields[0].ToString()),
            D2002_ServiceCategory = int.Parse(Fields[1]),
            D2003_Schedule3 = decimal.Parse(Fields[2]),
            D2004_ExemptCustomerFlag = (Fields[3].ToString() == "1" 
                ? true : false),
            D2005_CustomerClassification = Fields[4].ToString(),
            D2006_29e = decimal.Parse(Fields[5]),
            D2007_LargeVolAgreement = (Fields[6].ToString() == "1" 
                ? true : false),
            D2008_SICCode = (Fields[7].ToString() == "" ? -1 : int.Parse(Fields[7].ToString())),
            D2011_RateableValue = decimal.Parse(Fields[8]),
            D2014_FarmCroft = Fields[9].ToString(),
            D2015_SPIDVacant = (Fields[10].ToString() == "1" 
                ? true : false),
            D2018_TroughsDrinkingBowls = (Fields[11].ToString() == "1" 
                ? true : false),
            D2019_WaterServicesToCaravans = (Fields[12].ToString() == "1" 
                ? true : false),
            D2020_OutsideTaps = (Fields[13].ToString() == "1"
                 ? true : false),
            D2022_TransitionalArrangements = (Fields[14].ToString() == "1"
                 ? true : false),
            D2024_Unmeasurable = (Fields[15].ToString() == "1"
                 ? true : false),
            D2025_NotifyDisconnection_Reconnection = Fields[16].ToString(),
        };
        System.Diagnostics.Debug.WriteLine(i);
        Add(water);
        Save();
    }
}
 
     
     
    