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

时间:2017-06-14 11:02:42

标签: c# postgresql import bulkinsert fixed-width

我正在尝试将固定宽度文件中的数据插入到Postgresql表中。我来到图书馆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
            );            
    }
}

调试时,

  

实体

更新操作中此行的

参数

 insert.SaveAll(connection, entities); 

恰好为null,因此没有保存行并且它抛出“Object not set reference”错误。现在从关于这个CopyHelper库的有限文档中我无法弄清楚我必须使用哪个类或参数使用IEnumerable,因为SaveAll需要一个IEnumerable第二个参数

Debug Screen

从调试屏幕可以看出,我的pd(ProductData)具有存储在表中所需的值。如何将其与SaveAll方法中所需的IEnumerable参数链接?

Cant close writer, a row is still in progress, end it first

2 个答案:

答案 0 :(得分:1)

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

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添加条目。

答案 1 :(得分:0)

如果人们看不到评论部分,请添加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);