PostgreSQLCopyHelper 批量插入 Postgresql Table C# 固定宽度文件

PostgreSQLCopyHelper Bulk Insert Postgresql Table C# Fixed Width File

我正在尝试将固定宽度文件中的数据批量插入 Postgresql Table。我偶然发现了图书馆 PostgreSQLCopyHelper

https://github.com/bytefish/PostgreSQLCopyHelper

这是我在控制器中的更新操作(更新于 15/06/17)

        ProductData  pd = new ProductData();

        public ActionResult Update(q_product q_product, HttpPostedFileBase upload)
        {
        ProductData pd;
        var entities = new List<ProductData>();
        PostgreSQLCopyHelper<ProductData> insert;                       

        try
        {
            if(ModelState.IsValid && upload != null)
            {                    
                //uploaded file
                Stream stream = upload.InputStream;

                //need to use BULK INSERT or MULTIPLE INSERT at this point;                    

                //get the properties (columns) as set in ProductData.cs
                using (var fdr = new FileDataReader<ProductData>(stream))
                {
                    //read and get each line on imported file
                    while ((pd = fdr.ReadLine()) != null)
                    {
                        //Lets populate insert
                        //map table columns with properties
                        insert = new PostgreSQLCopyHelper<ProductData>("public", "q_product")
                            .MapUUID("q_guid", x => Guid.NewGuid())
                            .MapText("q_barcode", x => pd.barcode)
                            .MapText("q_description", x => pd.description)
                            .MapText("q_import_size", x => pd.size)
                            .MapNumeric("q_stocklevel", x => pd.quantity)
                            .MapText("q_import_vatcode", x => pd.vatCode) //vatcode is numeric in DB, this is a String (new column for this test)
                            .MapNumeric("q_casecost", x => pd.cost)
                            .MapNumeric("q_sellprice", x => pd.price);                            

                        //add the populated entries as we iterate through the file
                        entities.Add(pd);

                        using (var connection = new NpgsqlConnection("Host=192.168.0.52;Database=bolo;Username=western;Password=western"))
                        {
                            try
                            {
                                connection.Open();
                                insert.SaveAll(connection, entities);                                    
                                int lineCount = entities.Count();
                                TempData["SuccessMessage"] = lineCount+" Records Inserted!";
                            }
                            catch (Exception er)
                            {                                    
                                TempData["ErrorMessage"] = er.Message;
                                //TempData["ErrorMessage"] = "Error: importing records!";
                            }
                        }
                    }
                }

                return RedirectToAction("Index");
            }
        }

        catch(DataException error)
        {
            TempData["ErrorMessage"] = "Error importing records!";
            ModelState.AddModelError("", error.Message);
        }

        return RedirectToAction("Index");
    }

ProductData.cs 文件

public class ProductData 
{
    [Layout(22, 13)]
    public string barcode;        

    [Layout(49, 25)]
    public string description;

    [Layout(74, 5)]
    public string size;

    [Layout(95, 4)]
    public int quantity;

    [Layout(99, 1)]
    public string vatCode;

    [Layout(108, 7)]
    public decimal cost;

    [Layout(115, 7)]
    public decimal price;

    public override string ToString()
    {            
        return String.Format("string: {0}; string: {1}; string: {2}; int: {3}; string: {4}; decimal {5}; decimal {6}",
                barcode, description, size, quantity, vatCode, cost, price
            );            
    }
}

调试后,

entities

更新操作中这一行的参数

 insert.SaveAll(connection, entities); 

恰好为空,因此不会保存任何行并引发 "Object not set reference" 错误。现在,从有关此 CopyHelper 库的有限文档中,我无法弄清楚我必须使 IEnumerable 成为哪个 class 或参数,因为 SaveAll 需要一个 IEnumerable 第二个参数

正如您从调试屏幕中看到的那样,我的 pd (ProductData) 具有需要存储在 table 中的值。我如何 link 使用 SaveAll 方法中所需的 IEnumerable 参数?

我怀疑你想要这样的东西:

public ActionResult Update(q_product q_product, HttpPostedFileBase upload)
{    
    ProductData pd;
    var entities = new List<ProductData>();
    PostgreSQLCopyHelper<ProductData> insert = null;
    try
    {
        if(ModelState.IsValid && upload != null)
        {                    
            //uploaded file
            Stream stream = upload.InputStream;

            //need to use BULK INSERT or MULTIPLE INSERT at this point;                    

            //get the properties (columns)
            using (var fdr = new FileDataReader<ProductData>(stream))
            {
                //get each line on file
                while ((pd = fdr.ReadLine()) != null)
                {
                    //map table columns with properties
                    insert = insert ?? new PostgreSQLCopyHelper<ProductData>("public","q_product")
                        .MapUUID("q_guid", x => Guid.NewGuid())
                        .MapText("q_barcode", x => this.pd.barcode)
                        .MapText("q_description", x => this.pd.description)
                        .MapText("q_size", x => pd.size) 
                        .MapInteger("q_stocklevel", x => this.pd.quantity)
                        .MapText("q_vatcode", x => pd.vatCode)  
                        .MapMoney("q_casecost", x => this.pd.cost)
                        .MapMoney("q_sellprice", x => this.pd.price);
                    entities.Add(pd);
                }
            }
            using (var connection = new NpgsqlConnection("Host=192.168.0.52;Database=tester;Username=test;Password=test"))
            {
                try
                {
                    connection.Open();
                    insert.SaveAll(connection, entities);                                    
                    TempData["SuccessMessage"] = "Records Inserted!";
                }
                catch (Exception er)
                {
                    TempData["ErrorMessage"] = er.Message;                                    
                    //TempData["ErrorMessage"] = "Error importing records!";
                }
            }

            return RedirectToAction("Index");
        }
    }

    catch(DataException error)
    {
        TempData["ErrorMessage"] = "Error importing records!";
        ModelState.AddModelError("", error.Message);
    }

    return RedirectToAction("Index");
}

主要更改是仅填充 insert 一次,然后在遍历上传的文件时将条目添加到 entities

添加到 mjwillis 的令人敬畏和非常感谢的答案,如果看不到评论部分。以下代码使一切井井有条: 从

更改映射
.MapText("q_barcode", x => this.pd.barcode)

.MapVarchar("q_barcode", x => x.barcode)

如下

//map table columns with properties
                        insert = insert ?? new PostgreSQLCopyHelper<ProductData>("public", "q_product")
                            .MapUUID("q_guid", x => Guid.NewGuid())
                            .MapVarchar("q_barcode", x => x.barcode)
                            .MapVarchar("q_description", x => x.description)
                            .MapVarchar("q_import_size", x => x.size)
                            .MapNumeric("q_stocklevel", x => x.quantity)
                            .MapVarchar("q_import_vatcode", x => x.vatCode) 
                            .MapNumeric("q_casecost", x => x.cost)
                            .MapNumeric("q_sellprice", x => x.price);