2017-07-31 72 views
0

我有從我的視圖中的搜索查詢生成的記錄列表。有一些可以編輯的字段,下一步是用一個按鈕/動作更新這些字段。通過Request.Forms循環以獲取批量更新的字段值

See list on view

黃色的領域是已編輯的,而白色區域仍然匹配什麼是數據庫中的表。現在,當我點擊更新時,我首先從數據庫中獲取sellprice和casecost的值,然後從表單中獲取值。如果值匹配,則繼續前進,如果表單中的值已更改,則更新。我有datareader從表/數據庫中讀取頁面上每一行記錄的數據。

NpgsqlDataReader dr = cmd.ExecuteReader(); 

while (dr.Read()) 
{ 
    var prod = new ProductViewModel(); 

    prod.q_guid = Guid.Parse(dr["q_guid"].ToString());     
    prod.q_sellprice = Convert.ToDecimal(dr["q_sellprice"]);     
    prod.q_casecost = Convert.ToDecimal(dr["q_casecost"]);     

    /* 
    At this point 
    Need to compare dr.Read q_sellprice and q_casecost 
    with changed values in the fields 
    if != then update for that record 
    */ 

    /*Lets assign previous values (values in db) to variables*/ 
    var previousSellprice = prod.q_sellprice; 
    var previousCasecost = prod.q_casecost; 
    var thatId = prod.q_guid; 

    /*Lets get current values from form/list*/ 
    var priceList = Request.Form["item.q_sellprice"]; 
    var costList = Request.Form["item.q_casecost"]; 

    /*eg*/ 

    if (previousSellprice != currentSellprice || previousCasecost != currentCasecost) 
    { 
     //lets update record with new values from view 
    } 

    -> loop move on to next row in view 

我的DataReader while循環可以得到每行的值沒有問題。我想實現當它獲得的第一行的值,從數據庫,然後

  • 我需要檢查什麼樣的形式,該記錄的電流值是
  • ,如果他們是不同的,那麼更新對於當前行
  • 上/移動到下一行的視圖
  • 頁面

在我設法得到的值與這些變量與下面的代碼這些字段的數組。這具有來自列表/表格的編輯/更改的字段。

var priceList = Request.Form["item.q_sellprice"]; 
var costList = Request.Form["item.q_casecost"]; 

First run through loop

在我通過循環第一次運行,我想獲得如有必要值10.00和8.50,做我的支票,更新..然後下一行,將獲得3.33動和8.88,做我的檢查,並在必要時進行更新,以此類推,查看該頁面上的其他記錄。

那麼如何循環訪問實例中的Request.Forms,並一次獲取一條記錄的個人值?上視圖字段

CSHTML是

@foreach (var item in Model) 
{ 
    <td> 
     € @Html.EditorFor(modelItem => item.q_sellprice, new { name="q_sellprice" }) 
    </td> 
    <td> 
     € @Html.EditorFor(modelItem => item.q_casecost, new { name="q_casecost"}) 
    </td> 

增加:更新心不是問題,從陣列獲取每個記錄的值,同時通過表單字段循環是。

+0

我知道你已經添加了'Forms'標籤,但是這是一個非常通用的標籤。這是MVC還是ASP.Net Forms?此外,呈現的HTML對於回答這個問題非常重要。從我的猜測,你所有的銷售價格和案例成本都使用相同的「名稱」(因此值數組)。 – Nico

+0

這是MVC,我已經添加了問題中的字段的HTML。 – LavsTo

+0

您生成的視圖不正確,未綁定到您的模型。請參閱[這個答案](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943)瞭解如何正確生成一個集合的表單控件(和「新{ name =「q_sellprice」}'什麼也不做)。並且不要使用'Request.Form [...]' - 在POST方法中綁定到您的模型 –

回答

1

這是一個很長的問題描述 - 但根據我的理解,唯一的問題是,您想要獲得一些數據,現在是兩個字符串作爲操作列表(數據)來執行?那是對的嗎?

如果是這樣的 - 你可以使用Zip法列表中的這樣的數據:

void Main() 
    { 
     string priceList = "1,2,3,4"; 
     string costList = "2,3,4,5"; 
     var prices = priceList.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries); 
     var costs = costList.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries); 
     var collectionToUpdate = prices.Zip(costs, (price, cost) => new PriceToUpdate(price, cost)); 
     //do update in database with collectionToUpdate 
    } 

    public class PriceToUpdate 
    { 
     public PriceToUpdate(string oldPrice, string newPrice) 
     { 
      decimal priceTmp; 
      if (decimal.TryParse(oldPrice, out priceTmp)) 
      { 
       OldPrice = priceTmp; 
      } 
      if (decimal.TryParse(newPrice, out priceTmp)) 
      { 
       NewPrice = priceTmp; 
      } 
     } 
     public decimal OldPrice { get; set; } 
     public decimal NewPrice { get; set; } 
    } 
1

我的建議是重新組織你的HTML多一點,並修改方法獲得場解析出。我過去所做的是將Key Id(在您的案例中爲Guid)作爲輸出的一部分。所以導致基本觀點是這樣的:

Sample Html

如果您發現name屬性(和Id)與q_guid場前綴。這是我的基本模型。

public class ProductViewModelItems 
{ 
    public IList<ProductViewModel> items { get; set; } = new List<ProductViewModel>(); 
} 

public class ProductViewModel 
{ 
    public Guid q_guid { get; set; } 

    public decimal q_sellprice { get; set; } 

    public decimal q_casecost { get; set; } 

    //other properties 
} 

而我的控制器只是一個簡單的靜態模型。當然,你的是從你的數據庫構建的。

static ProductViewModelItems viewModel = new ProductViewModelItems() 
{ 
    items = new[] 
    { 
     new ProductViewModel { q_casecost = 8.50M, q_sellprice = 10M, q_guid = Guid.NewGuid() }, 
     new ProductViewModel { q_casecost = 8.88M, q_sellprice = 3.33M, q_guid = Guid.NewGuid() }, 
     new ProductViewModel { q_casecost = 9.60M, q_sellprice = 3.00M, q_guid = Guid.NewGuid() }, 
     new ProductViewModel { q_casecost = 9.00M, q_sellprice = 5.00M, q_guid = Guid.NewGuid() }, 
     new ProductViewModel { q_casecost = 10M, q_sellprice = 2.99M, q_guid = Guid.NewGuid() }, 
    } 
}; 

[HttpGet] 
public ActionResult Index() 
{ 
    //load your view model from database (note mine is just static) 
    return View(viewModel); 
} 

現在我們構建我們的表單,以便我們可以在我們的post方法中將其拉回。所以,我選擇的{q_guid}_{field_name}格式爲

  1. q_casecost = {q_guid}_q_casecost
  2. q_sellprice = {q_guid}_q_sellprice

的形式建設現在的樣子。

@foreach (var item in Model.items) 
{ 
    <tr> 
     <td> 
      € @Html.TextBoxFor(modelItem => item.q_sellprice, new { Name = string.Format("{0}_q_sellprice", item.q_guid), id = string.Format("{0}_q_sellprice", item.q_guid) }) 
     </td> 
     <td> 
      € @Html.TextBoxFor(modelItem => item.q_casecost, new { Name = string.Format("{0}_q_casecost", item.q_guid), id = string.Format("{0}_q_casecost", item.q_guid) }) 
     </td> 
    </tr> 
} 

請注意這裏有幾個關鍵項目。首先你不能使用EditorFor()修改Name屬性,所以我將它換成了TextBoxFor()方法。

接下來,我重寫了Name屬性(注意它必須是Name而不是name [小寫字母被忽略])。

最後,POST操作運行方式大不相同。

[HttpPost] 
public ActionResult Index(FormCollection form) 
{ 
    IList<ProductViewModel> updateItems = new List<ProductViewModel>(); 

    // form key formats 
    // q_casecost = {q_guid}_q_casecost 
    // q_sellprice = {q_guid}_q_sellprice 

    //load your view model from database (note mine is just static) 

    foreach(var item in viewModel.items) 
    { 
     var caseCostStr = form.Get(string.Format("{0}_q_casecost", item.q_guid)) ?? ""; 
     var sellPriceStr = form.Get(string.Format("{0}_q_sellprice", item.q_guid)) ?? ""; 

     decimal caseCost = decimal.Zero, 
       sellPrice = decimal.Zero; 

     bool hasChanges = false; 

     if (decimal.TryParse(caseCostStr, out caseCost) && caseCost != item.q_casecost) 
     { 
      item.q_casecost = caseCost; 
      hasChanges = true; 
     } 

     if(decimal.TryParse(sellPriceStr, out sellPrice) && sellPrice != item.q_sellprice) 
     { 
      item.q_sellprice = sellPrice; 
      hasChanges = true; 
     } 

     if (hasChanges) 
      updateItems.Add(item); 
    } 
    //now updateItems contains only the items that have changes. 

    return View(); 
} 

所以這裏有很多事情要做,但是如果我們把它分解得很簡單。首先,Action將接受一個FormCollection對象,該對象是原始表單,作爲NameValuePairCollection,它將包含表單的所有鍵\值。

public ActionResult Index(FormCollection form) 

下一步是從您的數據庫加載您的視圖模型,就像您以前所做的一樣。您正在加載的訂單並不重要,因爲我們會再次介紹它。 (注意,我只是像以前一樣使用靜態的)。

然後,我們遍歷您加載的視圖模型中的每個項目,現在正在解析FormCollection以外的表單值。

var caseCostStr = form.Get(string.Format("{0}_q_casecost", item.q_guid)) ?? ""; 
var sellPriceStr = form.Get(string.Format("{0}_q_sellprice", item.q_guid)) ?? ""; 

這將捕獲基礎上,再次q_guid回首,我們之前使用的格式表單中的值。

接下來,您將字符串值解析爲小數,並將它們與原始值進行比較。如果任一值(q_sellpriceq_casecost)不同,我們將其標記爲已更改並將其添加到updateItems集合中。

最後,我們updateItems變量現在包含所有有變化的元素,您可以將這些元素提交回數據庫。

我希望這會有所幫助。