asp:EntityDataSource failing to update or delete gridview - asp.net

I have a gridview of vendor bids that have foreign keys to a vendors table and a product table.
Here is my gridview and my datasource.
<table>
<asp:GridView ID="GridViewVendorBids" runat="server" AutoGenerateColumns="False"
DataSourceID="VendorBidsDS" DataKeyNames="autRecNum" ForeColor="#333333" CellPadding="4"
GridLines="None" AllowPaging="True" AllowSorting="True">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:CommandField ShowEditButton="true" />
<asp:BoundField DataField="dtmBidDate" HeaderText="Bid Date" SortExpression="dtmBidDate"
DataFormatString="{0:MM/dd/yyyy}" ApplyFormatInEditMode="true" />
<asp:TemplateField HeaderText="Vendor Name" SortExpression="it.tblVendors.strVendorName">
<ItemTemplate>
<asp:Label ID="lblVendorName" runat="server" Text='<%# Eval("tblVendors.strVendorName") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlVendorList" runat="server" DataTextField="strVendorName"
DataSource='<%# getVendorList() %>' DataValueField="strVendorCode" AutoPostBack="false"
SelectedValue='<%# Bind("strVendorCode") %>' DropDownStyle="DropDownList" AutoCompleteMode="SuggestAppend"
CssClass="comboBoxInsideModalPopup" Width="250px" MaxLength="0" Style="display: inline;
top: 0px; left: 0px;" ItemInsertLocation="Append" RenderMode="Inline" Height="16px" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product Name" SortExpression="it.tblProducts.strProductName">
<ItemTemplate>
<asp:Label ID="lblProductName" runat="server" Text='<%# Eval("tblProducts.strProductName") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlProductList" runat="server" DataTextField="strProductName"
DataSource='<%# getProductList() %>' DataValueField="strProductCode" AutoPostBack="false"
SelectedValue='<%# Bind("strProductCode") %>' DropDownStyle="DropDownList" AutoCompleteMode="SuggestAppend"
CssClass="comboBoxInsideModalPopup" Width="300px" MaxLength="0" Style="display: inline;
top: 0px; left: 0px;" ItemInsertLocation="Append" RenderMode="Inline" Height="16px" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Unit" SortExpression="it.tblProducts.strUnitDesc">
<ItemTemplate>
<asp:Label ID="lblUnitDesc" runat="server" Text='<%# Eval("tblProducts.strUnitDesc") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="sngBid" HeaderText="Bid" SortExpression="sngBid" ItemStyle-HorizontalAlign="Right"
DataFormatString="{0:0.00}" />
<asp:BoundField DataField="strBidType" HeaderText="Bid Type" SortExpression="strBidType"
ReadOnly="true" />
<asp:CommandField ShowDeleteButton="true" />
</Columns>
</asp:GridView>
</table>
<asp:EntityDataSource ID="VendorBidsDS" runat="server" ConnectionString="name=IMSEntities"
DefaultContainerName="IMSEntities" EntitySetName="tblVendorBid" Include="tblVendors,tblProducts"
EnableFlattening="False" OrderBy="it.dtmBidDate DESC" EnableDelete="true" EnableUpdate="true">
</asp:EntityDataSource>
When I press the update or delete key I get the following error:
No key property values were found during an update or delete operation. Check to ensure that key properties specified as binding expressions are available to the data source.
I found this post which is very similar to my problem but when I tried the answer I still get the same error.
Any help is appreciated. Thanks.

For the entity datasource you will need a primary key for the table.it allows you to change the records...After adding the primary key right click on entity datasource & select update database

Is "autRecNum" the only primary key of your VendorBidsDS Table?
You may check your Data Source Configuration whether primary key and foreign key are set properly. Also you may check if the Delete/Update Rule for FKey is set to Cascade if the other table is not updated.
And in " SelectedValue='<%# Bind("strProductCode") %>' ", "strProductCode" should be entity property instead of database column.
That's the few points I can remember from my previous project long long time ago.
Hope it can help you.

I got the "No key property values were found..." error because I was trying to save twice back to an EntityDataSource without a valid primary key. The StoreGeneratedPattern setting is correctly set to Identity and the first Insert ran correctly however the subsequent update fails - presumably because the primary key hasn't yet be set.
Basically I had manually inserted a row (using DbContext) and ran context.SaveChanges() but then my Telerik Grid translated the "Update" CommandName of the button to run another update command after the insert, causing this error. The error doesn't occur when updating existing rows, so it's very likely related to the primary key of a newly inserted row.
To solve the issue I simply set the CommandName of the button to "Cancel". My manual insert/update still runs, but then the Grid doesn't attempt another update operation and correctly closes the row I'm editing.

Related

How to add a tooltip to Boundfields in a Detailsview, but only if color of column has changed

I have the following code ...
<asp:DetailsView ID="dvApprenticeship" runat="server" DataSourceID="dsApprenticeship" AutoGenerateRows="false" BackColor="#E0E8F0" GridLines="None" CellPadding="2"
DataKeyNames="ProgramID, ProgramName, OrganisationName, StudyYearID, Workgroup, Pathway, FinishDate" OnDataBound="Apprenticeship_DataBound">
<Fields>
<asp:BoundField DataField="ProgramName" HeaderText="Program:" />
<asp:BoundField DataField="StudyYearName" HeaderText="Study Year:" />
<asp:HyperLinkField DataTextField="OrganisationName" HeaderText="Apprenticeship: " NavigateUrl="Apprenticeships.aspx" />
<asp:BoundField DataField="Workgroup" HeaderText="Workgroup:" />
<asp:BoundField DataField="Pathway" HeaderText="Pathway:" />
<asp:TemplateField HeaderText="Nominal Completion: ">
<ItemTemplate>
<asp:Label ID="labEndDate" runat="server" Text='<%# Eval("FinishDate","{0:d/MM/yyyy}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Fields>
<FooterTemplate>
<asp:LinkButton ID="lbAddProgramUnits" runat="server" OnClick="AddProgramUnits_Click" ForeColor="White" Font-Bold="true"
OnClientClick="return confirm('Import the Program Units listed - this may overwrite unit dates. Are you sure?');">Import from Program</asp:LinkButton>
Help
</FooterTemplate>
<FooterStyle HorizontalAlign="Center" BackColor="LightSlateGray" />
</asp:DetailsView>
I want to be able to show a tooltip whenever one of the above Boundfields has changed color.
In my C# codebehind, I have code that changes the color of these boundfields depending on certain conditions of the data. This is working fine.
But what I want is to be able to give the users a tooltip when ever they hover their mouse over these Boundfields and ONLY if that field is coloured differently, in my case
color.Yellow
.
And to answer my own question, with something else I found, which was overlooked: the convert BoundField to TemplateField option.
From this ...
<asp:BoundField HeaderText="Claim Type ID" ..etc../>
To This ...
<asp:TemplateField HeaderText="Claim Type ID">
<EditItemTemplate>
<asp:Label ID="lblClaimTypeID" runat="server" Text='<%# Eval("ClaimTypeID") %>' ToolTip="Enter a numerical value that conforms to the UserChoice Policy document (ie: 65 for GAT)."></asp:Label>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtClaimTypeID" runat="server" Text='<%# Bind("ClaimTypeID") %>' ToolTip="Enter a numerical value that conforms to the UserChoice Policy document (ie: 65 for GAT)."></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="itClaimTypeID" runat="server" Text='<%# Bind("ClaimTypeID") %>' ToolTip="A numerical value that conforms to the UserChoice Policy document (ie: 65 for GAT)."></asp:Label>
</ItemTemplate>
</asp:TemplateField>
This is sweet, because in the Design mode of ASPX, you can select your DetailsView, select the Edit Fields option and select the fields that are BoundFields and convert them straight into TemplateFields. The beauty with that, is that it converts the BoundFields to neat Labels or TextBoxes allowing you to directly code in a ToolTip property! And no code behind! Microsoft got something right there for once.
If you are setting the color to yellow in the DetailsView DataBound event based on some criteria, you can set the tooltip in that same block:
DetailsViewRow.Cells[indexofyellowfield].ToolTip = "some help from code-behind";

ASP.NET Dynamic Data Sorting on IDForeign Key

In my application we are using ASP.NET Dynamic Data for data binding. Everything works fine.
If you see the code snipped below, it has Dynamic Field DepartmentID which is a foreign key to Department table and gets the department name from there (this is specified in DynamicData/FieldTemplates/IDForeignKey.ascx.cs).
Our requirement is to sort (order by) the records on the department name as they are visible on the grid view. The only option that I have is to sort on DepartmentID which does not serve our purpose.
How can we sort on data that is retrieved from ForeignKey?
List.aspx
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridDataSource" OnPreRender="GridView1_PreRender"
AllowPaging="True" AllowSorting="True" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="EditHyperLink" runat="server"
NavigateUrl='<%# table.GetActionPath(PageAction.Edit, GetDataItem()) %>'
Text="Edit" /> | <asp:LinkButton ID="DeleteLinkButton" runat="server" CommandName="Delete"
CausesValidation="false" Text="Delete"
OnClientClick='return confirm("Are you sure you want to delete this item?");'
/>
</ItemTemplate>
</asp:TemplateField>
<asp:DynamicField DataField="DepartmentID" HeaderText="Department" />
<asp:DynamicField DataField="Description" HeaderText="Description"/>
</Columns>
<PagerStyle/>
<PagerTemplate>
<asp:GridViewPager runat="server" />
</PagerTemplate>
<EmptyDataTemplate>
There are currently no items in this table.
</EmptyDataTemplate>
</asp:GridView>
</div>
<asp:EntityDataSource OnSelecting="GridDataSource_Selecting" ID="GridDataSource" runat="server" EnableDelete="true" OnDeleted="GridDataSource_Deleted" >
<WhereParameters>
<asp:DynamicControlParameter ControlID="DynamicFilter1" />
</WhereParameters>
</asp:EntityDataSource>
Unfortunately it is not entirely clear from your question how are describe your metadata,
but anyway you can try to use QueryExtender control and SearchExpression class. More detail information you can find by link QueryExtender and SearchExpression with examples.
The whole idea of this is use custom LINQ.

How to get cell contents in ASP.NET GridView while handling OnRowEditing?

I have a GridView with a BoundField column and quite a few item templates like the following:
<asp:GridView ID="gvUsers" runat="server" AutoGenerateColumns="False" OnRowCommand="gvUsers_RowCommand"
OnRowDataBound="gvUsers_RowDataBound" DataKeyNames="UserId" OnRowEditing="gvUsers_OnRowEditing"
OnRowUpdating="gvUsers_OnRowUpdating" OnRowUpdated="gvUsers_OnRowUpdated"
DataSourceID="DataSource1" Width="807px" Height="105px"
AllowPaging="True" >
<Columns>
<asp:BoundField DataField="UserName" HeaderText="User Name"
SortExpression="UserName" />
<asp:TemplateField HeaderText="Approver">
<ItemTemplate>
<asp:CheckBox ID="cbApprover" runat="server" Enabled="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Auditor">
<ItemTemplate>
<asp:CheckBox ID="cbAuditor" runat="server" Enabled="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnEdit" runat="server"
CommandArgument='<%# Eval("UserName") %>' CommandName="Edit" Text="Edit" />
<asp:Label ID="lblPipe1" runat="server" Text=" | " />
<asp:LinkButton ID="btnUpdate" runat="server"
CommandArgument='<%# Eval("UserName") %>' CommandName="Update" Text="Update" />
<asp:Label ID="lblPipe" runat="server" Text=" | " />
<asp:LinkButton ID="btnDelete" runat="server"
CommandArgument='<%# Eval("UserName") %>' CommandName="Remove"
OnClientClick="return confirm('Are you sure you want to delete this user?');"
Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
While handling the Edit link button I need to use the value in the BoundField, UserName. Unfortunately during the OnRowEditing handler, all strings are empty "". This is also true in the ensuing OnRowDataBound handler for the row in question where e.Row.RowState == DataControlRowState.Edit. Is there a way to obtain this value after the user clicks on the Edit link, and commences the OnRowEditing event?
I arrived at a solution that was a bit more complicated than I was hoping for. I'll show code later but I did the following:
Created a HiddenField to hold the
value of the cell I wanted to edit in
its view state.
In the OnRowDataBound handler, I assigned the value to the
HiddenField.
The ItemTemplate, as seen above, sends the UserName as an
argument. I store this value in
the HiddenField.
The OnRowEditing is fired after the Command handler. That is where I
read the HiddenField.
If anyone has a simpler solution I would love hear about it.
Could it be that you're using late binding in TemplatedItems without EditItemTemplates?

Using Repeater Control as a command parameter for a nested gridview

I have a repeater which contains a nested gridview. Now I need to be able to retrieve a value databound in a label inside of a repeater and use it as an input parameter for the gridview.
Here is some code which will hopefully give you a better idea of what I'm trying to do.
enter code here
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="RepeaterDS" OnItemDataBound="Repeater1_SendRollNumber">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<table style="width: 615px;" id="Table1">
<tr>
<td>
<b>Roll #:</b>
<asp:Label runat="server" ID="RollIDLabel" Text='<%# Eval("RollID") %>' />
<asp:Label runat="server" ID="RollIDLabelCode" Text='<%# Eval("RollID") %>' Visible="false" />
</td>
</tr>
<tr>
<td>
<b>Address:</b>
<asp:Label runat="server" ID="AddressLabel" Text='<%# Eval("Address") %>' />
</table>
<asp:Label ID="Label1" runat="server"><b>Parties:</b></asp:Label>
<asp:GridView ID="GridView3" runat="server" BackColor="White" BorderColor="#DEDFDE"
BorderStyle="None" BorderWidth="1px" CellPadding="4" ForeColor="Black" GridLines="Vertical"
AllowPaging="True" Width="620px" DataSourceID="AssessmentDetailsFromRollIDDS"
EmptyDataText="None Associated" AutoGenerateColumns="False" ShowFooter="true">
<asp:TemplateField HeaderText="Property Assessment" HeaderStyle-Font-Bold="true"
FooterStyle-BackColor="White">
<ItemTemplate>
<asp:Label ID="PropAssessType" runat="server" Width="90%" Text='<%# Eval("PropertyAssessmentType") %>'></asp:Label>
<asp:Label ID="PropAssessDsc" runat="server" Text='<%# Eval("PropertyAssessmentDesc") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:TemplateField>
<RowStyle BackColor="#F7F7DE" />
<FooterStyle BackColor="#CCCC99" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#3E4E4E" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="RepeaterDS" runat="server" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetRollNumberbyAppealID" TypeName="BusinessLayer.BSO.Roll_AssessmentDetailsBSO">
<SelectParameters>
<asp:QueryStringParameter Name="AppealID" QueryStringField="appealID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="AssessmentDetailsFromRollIDDS" runat="server" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetAssessDetailsFromRollID" OnSelecting="AssessmentDetailsFromRollIDDS_Selecting" TypeName="BusinessLayer.BSO.Assessment_DetailsBSO">
<SelectParameters>
<asp:ControlParameter Name="RollID" ControlID="RollIDLabelCode" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
I've tried to cut out as much code as possible while leaving the guts of the problem in. So I basically want the label control RollIDLabelCode which is located in a repeater to also be an input into my gridview. The problem is that I keep getting errors such as can't find the control RollIDLabelCode. I've heard there is a bug in which you need to specify all naming containers. which I've tried with no luck.
Another route I've tried is doing this in the code behind.
enter code here
public void Repeater1_OnItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string test = ((Label)e.Item.FindControl("RollIDLabel")).Text;
}
}
public void AssessmentDetailsFromRollIDDS_OnSelecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["RollID"] = "Need the Info here";
}
These functions are called on the repeater being databound and the objectdatasource onselecting function. And these work separately very well. I just need to know how to get the information from the string test in the Repeater1_OnItemDataBound function to the e.InputParameters["RollID"] in the OnSelecting function.
Hopefully someone knows how to do this. I am new to .net programming. I appreciate any help.
Thanks!
The RollIDLabelCode label is set visible=false which means it will not exist when rendered so trying to access the value won't be possible. You'll need to use a different control that is hidden but exists when rendered. For instance a GridView has a datakeys that exist within the control but are not rendered. It is used to retrieve a key value for the row to retreive more data, for example.

DataBinding: 'DynamicClass1' does not contain a property with the name 'EmployeeID'

i have used aggregate function in List Page of dynamic datawebsite. When it execute it gives me,
DataBinding: 'DynamicClass1' does not contain a property with the name 'EmployeeID'.
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridDataSource"
AllowPaging="True" AllowSorting="True" CssClass="gridview">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="EditHyperLink" runat="server"
NavigateUrl='<%# table.GetActionPath(PageAction.Edit, GetDataItem()) %>'
Text="Edit" /> <asp:LinkButton ID="DeleteLinkButton" runat="server" CommandName="Delete"
CausesValidation="false" Text="Delete"
OnClientClick='return confirm("Are you sure you want to delete this item?");'
/> <asp:HyperLink ID="DetailsHyperLink" runat="server"
NavigateUrl='<%# table.GetActionPath(PageAction.Details, GetDataItem()) %>'
Text="Details" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="footer"/>
<PagerTemplate>
<asp:GridViewPager runat="server" />
</PagerTemplate>
<EmptyDataTemplate>
There are currently no items in this table.
</EmptyDataTemplate>
</asp:GridView>
<asp:LinqDataSource ID="GridDataSource" runat="server"
ContextTypeName="DataClassesDataContext"
TableName="Employees"
GroupBy="EmployeeNo"
Select="new(Key,
Max(Version) As VersionNo)"
EnableDelete="true">
<WhereParameters>
<asp:DynamicControlParameter ControlID="FilterRepeater" />
</WhereParameters>
</asp:LinqDataSource>
I have not changed any of the default code except i have added ContextTypeName,TableName, GroupBy and select in Linq Data source...
Table "Employees" has "EmployeeID, EmployeeNo, EmployeeName, Department, Address, City, State, Country, Version" as columns..
Any idea how to solve this?
Thanks in advance!
Regards,
Bala
The problem is that you're grouping doesn't create the type of data that the grid is expecting to receive. GetDataItem() is expecting a particular type of data and that's not what you've set up in your LinqDataSource.
Your select needs to include all the items that GetDateItem() needs, right now it doesn't:
new(Key, Max(Version) As VersionNo) //EmployeeID needs to be included here
new(Key, Max(Version) As VersionNo) is fine.
To Get the Employee... use: Key.Employee
The Key is a dynamic class containing all the properties specified in the group by statement.
Anything else (ie EmployeeNo, EmployeeName, Department, Address, City, State, Country, Version) will need an aggregate statement (ie Sum, Max, Min).

Resources