MVC将csv文件上载到数据库,但选择要插入的列

时间:2015-02-28 23:16:35

标签: c# sql razor model-view-controller datatable

需要一些帮助才能将数据从csv文件上传到数据库。数据库(当然)有预先指定的列名,我想让用户选择CSV文件中的哪些列转到数据库中的哪些列。

查看代码:

@using (Html.BeginForm("Index", "Upload", FormMethod.Post, new { @enctype = "multipart/form-data" }))
{
    <input type="file" name="FileUpload" style="margin-left:40px;cursor:pointer;" />
    <br />
    <input type="submit" style="margin-left:40px;cursor:pointer;" id="upload" value="Upload" />
}

控制器:

[HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase FileUpload)
    {
        // Set up DataTable place holder
        DataTable dt = new DataTable();
string fileName = Path.GetFileName(FileUpload.FileName);
string path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
FileUpload.SaveAs(path);
dt = ProcessCSV(path);

return view(dt);}

private static DataTable ProcessCSV(string fileName)
    {
        //Set up our variables
        string Feedback = string.Empty;
        string line = string.Empty;
        string[] strArray;

        DataTable dt = new DataTable();
        DataRow row;

        // work out where we should split on comma, but not in a sentence
        Regex r = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");

        //Set the filename in to our stream
        StreamReader sr = new StreamReader(fileName);

        //Read the first line and split the string at , with our regular expression in to an array
        line = sr.ReadLine();
        strArray = r.Split(line);

        //For each item in the new split array, dynamically builds our Data columns. Save us having to worry about it.
        Array.ForEach(strArray, s => dt.Columns.Add(new DataColumn()));

        //Read each line in the CVS file until it’s empty
        while ((line = sr.ReadLine()) != null)
        {
            row = dt.NewRow();

            //add our current value to our data row
            row.ItemArray = r.Split(line);
            dt.Rows.Add(row);
        }

        //Tidy Streameader up
        sr.Dispose();

        //return a the new DataTable
        return dt;

    }

所以我设法将文件上传到服务器,将数据从csv文件读入数据表。现在我只需要将数据库列与数据库中的列名列表一起返回给用户,然后用户可以选择应该进入的列。

我现在需要一个以新形式显示列名的视图。这是我真正需要帮助的地方,不知道如何将导入的CSV中的列名称传递回视图,然后将选定的列名称传递回控制器。

    @model System.Data.DataTable
@using System.Data;

<h2>Columns to include</h2>

@using (Html.BeginForm())
<table>
    <thead>
        <tr>
            <th>Column name</th>
            <th>Select database column name</th>
        </tr>
    </thead>
    <tbody>
        @foreach (DataColumn col in Model.Columns)
        {
        <tr>
            <td>
                @col.ColumnName
            </td>
            <td>

            </td>
        </tr>

        }
    </tbody>
</table>

我希望最终能够使用这样的东西

                    SqlBulkCopyColumnMapping ColFirstName = new SqlBulkCopyColumnMapping("Column1", "Firstname");
                SqlBulkCopyColumnMapping ColLastName = new SqlBulkCopyColumnMapping("Column2", "Surname");
                SqlBulkCopyColumnMapping ColDOB = new SqlBulkCopyColumnMapping("Column3", "Dateofbirth");

                copy.ColumnMappings.Add(ColFirstName);
                copy.ColumnMappings.Add(ColLastName);
                copy.ColumnMappings.Add(ColDOB);

1 个答案:

答案 0 :(得分:0)

public class ColumsViewModel
{
    public string[] SelectedNames { get; set; }

    public IEnumerable<SelectListItem> Names { get; set; }
}

扩展您的公共ActionResult UploadFile

var model = new SearchViewModel();

        var names = dt.Columns.Select(x => new SelectListItem
        {
            Value = x.ColumnName,
            Text = x.ColumnName
        }).ToList();

 model.Names = names;
 return View(model);

在视图中替换@foreach:

@model namespace.ViewModels.ColumsViewModel

@using (Html.BeginForm("SelectedColumns", "Home", FormMethod.Post))
{
     @Html.ListBoxFor(m => m.SelectedNames, Model.Names, new Dictionary<string, object> { { "size", "15" } })
}

使用CTRL +鼠标单击选择多个值。

创建行动:

[HttpPost]
    public ActionResult SelectedColumns(ColumsViewModel model)
    {
          //you will have your selected columns in model.SelectedNames
          //now you can do what you need with them
    }

可能有一些拼写错误,因为我没有用VS进行实际测试,所以你可以修复它。重要的是抓住这个想法。