views:

66

answers:

1

I have imports.aspx with an ASP:FileUpload function.

In my code-behind I have this:

SEPTA_DSTableAdapters.ServiceTBLTableAdapter sta = new SEPTA_DSTableAdapters.ServiceTBLTableAdapter();
    SEPTA_DSTableAdapters.RoutesTBLTableAdapter rta = new SEPTA_DSTableAdapters.RoutesTBLTableAdapter();
    protected void Page_Load(object sender, EventArgs e)
    {
        ServiceDDL.DataBind();
    }
    protected void Submit_Click(object sender, ImageClickEventArgs e)
    {
        if (ImportRoutes.HasFile)
        {
            //Parse CSV
            StreamReader reader = new StreamReader(ImportRoutes.FileContent);
            var pathOfCsvFile = reader;
            var adapter = new GenericParsing.GenericParserAdapter(pathOfCsvFile);
            DataTable data = adapter.GetDataTable();

            foreach (DataRow row in data.Rows)
            {
                int insertData = Convert.ToInt32(rta.InsertRoutes(Convert.ToInt32(row["RouteID"]), ServiceDDL.SelectedValue, row["ShortName"].ToString(), row["LongName"].ToString(), row["Type"].ToString(), row["Url"].ToString()));
            }
        }
    }

Here is a sample of the code I am importing:

route_id,route_short_name,route_long_name,route_desc,agency_id,route_type,route_color,route_text_color,route_url
AIR,AIR,Airport Line, ,SEPTA,2,44697D,FFFFFF,
CHE,CHE,Chestnut Hill East, ,SEPTA,2,44697D,FFFFFF,
CHW,CHW,Chestnut Hill West, ,SEPTA,2,44697D,FFFFFF,
CYN,CYN,Cynwyd, ,SEPTA,2,44697D,FFFFFF,

And my Database columns are:

RouteID
Category
ShortName
LongName
Type
Url

Here is my Insert query:

INSERT INTO [dbo].[RoutesTBL] ([RouteID], [Category], [ShortName], [LongName], [Type], [Url]) VALUES (@RouteID, @Category, @ShortName, @LongName, @Type, @Url)

Here is the StackTrace

[ArgumentException: Column 'RouteID' does not belong to table .]
   System.Data.DataRow.GetDataColumn(String columnName) +1775301
   System.Data.DataRow.get_Item(String columnName) +13
   Import.Submit_Click(Object sender, ImageClickEventArgs e) in c:\Documents and Settings\abpa\Desktop\ASP\SEPTAWeb\Import.aspx.cs:32
   System.Web.UI.WebControls.ImageButton.OnClick(ImageClickEventArgs e) +108
   System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument) +118
   System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

Now, I have two questions.

  1. I am getting a row does not exist error on the int insertData portion, how can I fix that?

  2. The first row of the file is clearly the column names to the CSV, but when inserting I need this row skipped.

Thank in advance all.

+1  A: 

Your first issue is here:

DataTable data = adapter.GetDataTable();

foreach (DataRow row in data.Rows)
{
    int insertData = Convert.ToInt32(rta.InsertRoutes(Convert.ToInt32(row["RouteID"]), ServiceDDL.SelectedValue, row["ShortName"].ToString(), row["LongName"].ToString(), row["Type"].ToString(), row["Url"].ToString()));
}

As you've shown in the CSV sample, your columns in the file are route_id,route_short_name,route_long_name,route_desc,agency_id,route_type,route_color,route_text_color,route_url, but in your code you're attempting to get a column called RouteId from the row, try:

int insertData = Convert.ToInt32(rta.InsertRoutes(Convert.ToInt32(row["route_id"]), ServiceDDL.SelectedValue, row["route_short_name"].ToString(), row["route_long_name"].ToString(), row["route_type"].ToString(), row["route_url"].ToString()));

For your second problem, there is a property you can set on the GenericParserAdapter to define whether the first row is treated as headers or data, take a look at the help file (.chm) that accompanies it to determine precisely what it's called. I suspect it's already skipping this row however.

On a side note, you might want to think about re-structuring your code to make it more readable, maintainable and debuggable. Try this instead:

var routeId = Convert.ToInt32(row["route_id"]);
var routeShortName = Convert.ToString(row["route_short_name"]);
var routeLongName = Convert.ToString(row["route_long_name"]);
var routeType = Convert.ToString(row["route_type"]);
var routeUrl = Convert.ToString(row["route_url"]);

int insertData = Convert.ToInt32(rta.InsertRoutes(routeId, ServiceDDL.SelectedValue, routeShortName, routeLongName, routeType, routeUrl));

More readable, eh?

If you're able to add a reference to System.Data.DataSetExtensions (i.e. .net 3.5) you then can use the DataRow.Field<T> extension method for even cleaner looking code:

var routeId = row.Field<int>("route_id");
var routeShortName = row.Field<string>("route_short_name");
var routeLongName = row.Field<string>("route_long_name");
var routeType = row.Field<string>("route_type");
var routeUrl = row.Field<string>("route_url");
Rob
@Rob I did have `"route_id"` it didn't work. I also know I could have shortened it and made it more readable as well. Knowing that it was `"route_id"` how come it doesn't work?
Bry4n
@Bry4n, put a breakpoint on the line `foreach (DataRow row in data.Rows)` and then use the Visual Studio Debugger to look into the `data` table to see what columns it contains, that'll be a good starting point for working out what's wrong =)
Rob
@Rob Yeah now I am getting this error `Column 'route_id' does not belong to table .` on `var routeId = Convert.ToInt32(row["route_id"]);` I will do that now.
Bry4n
@Rob shows an 8number ItemArray, `[0] = "route_id" [1] = "route_short_name"` etc etc
Bry4n
@Rob the `data.Rows` ItemArray has all the rows including the column names in it as well.
Bry4n
@Bry4n, have you reviewed the accompanying help (i.e. the .chm file that comes with the DLL in the zip file from codeproject) to look for the property on the `GenericParserAdapter` that you can set to tell it that the first row is Column Headers, rather than data? =)
Rob
@Rob got it. `adapter.FirstRowHasHeader = true;` This fixes question 2. But that error hasn't dissipated.
Bry4n
@Bry4n, the stack trace says `Column 'RouteID' does not belong to table` in question 2 you state the error is `row does not exist` - which error is it actually? If you use the Debugger, does it show the datatable contains the correct rows? I'm beginning to suspect that the `rta.InsertRoutes` method is where the error lies
Rob
@Rob I just had a break through actually. I changed `row` to `adapter` for `routeid` and it worked. EXCEPT `routeid` was given all zeros.
Bry4n
Changing it to `adapter` would be entirely the wrong thing to do, especially a it's returning zero's when `route_id` is supposed to be a 3 letter text string! =) Use the "break-out" version of code I suggested above, and tell me where the error occurs then... if it's still on the `rta.InsertRoutes` method, then it's something in there at fault and you'll need to **step into** that method to work out what's going wrong in there!
Rob
@Rob Not sure what happened, but now the entire thing works. I think the issue was routeId was set to an INT in the DB and it was a string in the file even though we were explicitly converting it to an Int. Regardless, it works and that is all that matters! woo
Bry4n