The theory seems to be to add an empty record to the Entity Framework Data Table, DataBind that DataSource to the GridView control, and Edit the Index of that newly inserted record:
Private Const ID_INDEX As Int32 = 1,
NAME_INDEX As Int32 = 2,
PHONE_INDEX As Int32 = 3,
FAX_INDEX As Int32 = 4,
EMAIL_INDEX As Int32 = 5,
ENABL_INDEX As Int32 = 6
Protected Sub AddNew_Clicked(sender As Object, e As EventArgs) Handles lbAddNew.Click
Dim data As New Employee()
Using db As New DataClassesDataContext()
db.Employees.Attach(data)
' db.Employees.AddObject(data)
gridView1.DataSource = db.Employees
gridView1.DataBind()
Dim result As IQueryable(Of Employee) = From x As Employee In db.Employees
Where x.emp_id = data.emp_id
If (result IsNot Nothing) Then
Dim added As Employee = result.FirstOrDefault()
For index As Int32 = 0 To gridView1.Rows.Count - 1
Dim cells As TableCellCollection = gridView1.Rows(index).Cells
Dim emp_id As Int32 = CInt(cells(ID_INDEX).Text)
If (data.emp_id = emp_id) Then
gridView1.EditIndex = index
End If
Next
End If
End Using
End Sub
The EditIndex value is correctly set, but there is no empty row for me to edit.
Here is the GridView control:
<asp:LinkButton ID="lbAddNew" runat="server" OnClientClick="AddNew_Clicked">Add New</asp:LinkButton><br />
<asp:GridView ID="gridView1" runat="server" HorizontalAlign="Left"
AutoGenerateColumns="False"
AllowDeleting="True"
AllowEditing="True"
BorderStyle="Solid"
PageSize="30"
OnRowCancelingEdit="gv_RowCancelEdit"
OnRowEditing="gv_RowEditing"
OnRowUpdating="gv_RowUpdating"
OnRowDataBound="gv_RowDataBound" DataKeyNames="emp_id">
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="true" />
<asp:BoundField DataField="emp_id" HeaderText="ID" InsertVisible="false" ReadOnly="true" SortExpression="emp_id" />
<asp:BoundField DataField="emp_name" HeaderText="Name" SortExpression="emp_name" />
<asp:BoundField DataField="emp_phone" HeaderText="Phone" SortExpression="emp_phone" />
<asp:BoundField DataField="emp_fax" HeaderText="Fax" SortExpression="emp_fax" />
<asp:BoundField DataField="emp_email" HeaderText="Email" SortExpression="emp_email" />
<asp:BoundField DataField="enabled" HeaderText="Enabled" SortExpression="enabled" />
</Columns>
</asp:GridView>
How do I add an empty row for editing?
That is a bit backwards. You normally do not insert an "empty" row into the database then refresh the grid to edit it. Instead you handle the insert row client side (grid) and enter the values, then when posting the Save from the data grid passing the data to make up the new record:
// C# code, my VB.Net is way outta date
[HttpPost]
public IActionResult InsertEmployee(string name, string phone, ...)
{
try
{
var employee = new Employee(name, phone, ...);
using var db = new DataClassesDataContext();
db.Employees.Add(employee); // Employee will be tracked as a new item.
db.SaveChanges();
return Ok(); // or re-direct, however suits your front end flow.
}
catch (Exception ex)
{
// handle exception and response... or
throw;
}
}
The problem with trying to pre-insert a data row is that your database should have constraints and such for what data is required vs. optional which means for instance if Name is not null-able you cannot insert a new employee without a name. Capture the info client-side, send the data to the server, and have the server attempt to create the row on completion.
As for the act of inserting a row, simply create the entity, add it to the DbSet, and call SaveChanges()
. When performing an update on an existing record, fetch the entity from the database, set the values, and call SaveChanges()
. You will see examples that pass entities back and forth in web applications, don't follow these examples because they almost always lead to issues with tracking errors, insert errors, duplicate data, etc. Web applications do not work the same way as WPF might where a DbContext and entity tracking might be kept alive through an editing process. MVC/WebAPI controllers may give the impression that is what is happening, but it is a lie of convenience. Entities don't travel between server & client & back, only primitive values. Controllers can just materialize new, detached (and often incomplete) entities from those values.