0

I'm trying to save a generic List to a SQL Database. The code takes a HTML Table file and pulls out each column using HTMLAgilityPack. When I set the contract.ToList(); to a Datalist and display it, the data is correct. Now I'm having trouble saving it to the SQL Database.

I thought I should store the list in a DataTable then use SQLBulkCopy, but I get an error "Unable to cast object of type 'System.Collections.Generic.List`1[ContractsImporter.Form1+Contract]' to type 'System.Data.DataTable'." with the code below

DataTable dt = (DataTable)(dataGridView1.DataSource);
                dataGridView2.DataSource = dt;

I'm still trying to learn C# so is their a better way than what i'm trying to do?

Thanks for any feedback.

Also the SQL Table column names are the same contact variable names in the program.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using HtmlAgilityPack;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace ContractsImporter
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonBrowse_Click(object sender, EventArgs e)
        {
            var DB = new System.Windows.Forms.OpenFileDialog();
            if (DB.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string fileToOpen = DB.FileName;
                textBoxImport.Text = fileToOpen;

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public static void ImportData()
        {
            SqlConnection thisConnection = new SqlConnection("Server=sqlsrv1;Initial Catalog=LoadData;User ID=user;Password=password");
            SqlCommand nonqueryCommand = thisConnection.CreateCommand();
        }

        public class Contract
        {
            public int ID { get; set; }
            public string AssetManager { get; set; }
            public string BillingAddress { get; set; }
            public string BillingCity { get; set; }
            public string BillingState { get; set; }
            public string BillingZip { get; set; }
            public string ContractAmount { get; set; }

        }

        private void buttonImport_Click(object sender, EventArgs e)
        {
            testing();

        }

        public void testing()
        {

            var data = File.ReadAllText(textBoxImport.Text);
            var table = new DataTable("ImportTable");

            string xmlData;


            var document = new HtmlAgilityPack.HtmlDocument();
            document.LoadHtml(data);
            document.OptionOutputAsXml = true;


            using (var stream = new StringWriter())
            using (var writer = XmlWriter.Create(stream))
            {
                document.Save(writer);
                xmlData = stream.ToString();
            }


            var contract =
                XDocument.Parse(xmlData)
                        .XPathSelectElements("//table/tr")
                        .Skip(1)
                        .Select(x => new Contract
                        {
                            ID = int.Parse(x.Elements("td").First().Value),
                            AssetManager = x.Elements("td").Skip(1).First().Value,
                            BillingAddress = x.Elements("td").Skip(2).First().Value,
                            BillingCity = x.Elements("td").Skip(3).First().Value,
                            BillingState = x.Elements("td").Skip(4).First().Value,
                            BillingZip = x.Elements("td").Skip(5).First().Value,
                            ContractAmount = x.Elements("td").Skip(6).First().Value,
                            });

            dataGridView1.DataSource = contract.ToList();

            DataTable dt = (DataTable)(dataGridView1.DataSource);
            dataGridView2.DataSource = dt;

            label1.Text = "Done";
        }
    }
}
Zach
  • 328
  • 2
  • 7
  • 21
  • Sorry forgot to paste the error. I edited it above. – Zach Jul 09 '13 at 18:49
  • Unless I'm missing something you don't seem to be using HTMLAgilityPack for what it's intention is. You are getting HTML and saving it back into a stream and then using LINQ2XML to pull the data back out again?! Why not just use the `HtmlDocument` directly? – Arran Jul 09 '13 at 18:49
  • 1
    There's no built in way to convert a list to a datatable. However you can use this [Convert generic List/Enumerable to DataTable](http://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable/564373#564373) – Conrad Frix Jul 09 '13 at 18:52
  • For all the work you are doing work around getting a 'Contract' object you should consider just using Entity Framework model and saving to the database with Entity Framework. Entity Models work much better with things like List to manipulate those objects back and forth from a database. You are essentially doing more of an entity type system then trying to convert it to the disconnected layer of the ADO.NET and then save via ADO.NET. I would just do entity framework IMHO. – djangojazz Jul 09 '13 at 18:57

0 Answers0