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
  • 348
  • 3
  • 7
  • 22
  • 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<(yourcustomobject)> 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