I'm looking for some help on binding a Codefluent entitycollection with an Infragistics WebHierarchicalDataGrid (v14.2). For illustrative purposes, I have two Codefluent entities: Customer and Order; where one related customer has many related orders.
On my ASP page, I have created the WebHierarchicalDataGrid, the WebHierarchicalDataSource, and two objectDataSources. For the WebHierarchicalDataSource I created two DataViews along with their DataRelations. The WebHierarchicalDataGrid's DataMember, Key, and DataKeyFields are all set correctly.
If the objectDataSources SelectMethods are set to the LoadAll methods of the CustomerCollection and the OrderCollection, the WebHierarchicalDataGrid displays as expected - that is the customer rows have nested order rows in the grid, and clicking on the +expansion icon displays the customer's order rows.
What I am trying to do is display the WebHierarchicalDataGrid for a single customer based on a user's input in a textbox on the webpage.
In the code behind I set the Customer's objectDataSource's SelectMethod to a method (LoadByCustomerID) defined in the Codefluent model which contains one paramameter (CustomerID) which I set to the value from the text box. I then call the Customer's objectDataSources Select method. This returns the desired Customer entity as expected.
From the returned Customer entity, I use data from a field (GUID) in the Customer entity to supply the SelectMethod (LoadOrdersByCustomerGUID) of the Order's objectDataSources. This too returns the expected OrderCollection of one or more related customer orders.
The results displayed in the WebHierarchicalDataGrid is only that of the parent row (the selected Customer). There is a +expansion icon displayed in the Customer row, but clicking on the +expansion icon does not display the retrieved order records for the selected customer.
How do I get the WebHierarchicalDataGrid to display the customer's related orders when the +expansion icon is clicked?
<ig:WebHierarchicalDataGrid ID="hdg_Customer" runat="server"
Height="600px" Width="95%"
AutoGenerateBands="False" AutoGenerateColumns="False"
DataMember="ods_Customer_DefaultView"
DataSourceID="hds_Customer"
Key="ods_Customer_DefaultView"
DataKeyFields="GUID"
Enabled="False" >
<Bands>
<ig:Band
AutoGenerateColumns="False"
DataMember="ods_Orders_DefaultView"
Key="ods_Orders_DefaultView"
DataKeyFields="GUID" >
<Columns>
<ig:BoundDataField DataFieldName="GUID" Key="GUID">
<Header Text="Order GUID">
</Header>
</ig:BoundDataField>
<ig:BoundDataField DataFieldName="OrderDate" Key="OrderDate">
<Header Text="Order Date">
</Header>
</ig:BoundDataField>
<ig:BoundDataField DataFieldName="TotalOrderAmount" Key="TotalOrderAmount">
<Header Text="Total Order Amount">
</Header>
</ig:BoundDataField>
<ig:BoundDataField DataFieldName="relatedCustomerGUID" Key="relatedCustomerGUID">
<Header Text="related Customer GUID">
</Header>
</ig:BoundDataField>
</Columns>
</ig:Band>
</Bands>
<Columns>
<ig:BoundDataField DataFieldName="GUID" Key="GUID">
<Header Text="Customer GUID">
</Header>
</ig:BoundDataField>--%>
<ig:BoundDataField DataFieldName="CustomerID" Key="CustomerID">
<Header Text="Customer ID">
</Header>
</ig:BoundDataField>
<ig:BoundDataField DataFieldName="CustomerName" Key="CustomerName">
<Header Text="Customer Name">
</Header>
</ig:BoundDataField>
<ig:BoundDataField DataFieldName="CustomerState" Key="CustomerState">
<Header Text="Customer State">
</Header>
</ig:BoundDataField>
</Columns>
</ig:WebHierarchicalDataGrid>
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"></asp:ScriptManagerProxy>
<ig:WebHierarchicalDataSource ID="hds_Customer" runat="server">
<DataViews>
<ig:DataView ID="ods_Customer_DefaultView"
DataMember="DefaultView"
DataSourceID="ods_Customer" />
<ig:DataView ID="ods_Orders_DefaultView"
DataMember="DefaultView"
DataSourceID="ods_Orders" />
</DataViews>
<DataRelations>
<ig:DataRelation
ChildColumns="relatedCustomerGUID"
ChildDataViewID="ods_Orders_DefaultView"
ParentColumns="GUID"
ParentDataViewID="ods_Customer_DefaultView" />
</DataRelations>
</ig:WebHierarchicalDataSource>
<asp:ObjectDataSource ID="ods_Orders" runat="server"
DataObjectTypeName="Accounts.Order"
OldValuesParameterFormatString="original_{0}"
SelectMethod="LoadAll"
TypeName="Accounts.OrderCollection" >
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="ods_Customer" runat="server"
DataObjectTypeName="Accounts.Customer"
OldValuesParameterFormatString="original_{0}"
SelectMethod="LoadAll"
TypeName="Accounts.CustomerCollection" >
</asp:ObjectDataSource>
</asp:Content>
select Customer and related Orders
(tried substituting this):
<asp:ObjectDataSource ID="ods_Orders" runat="server"
DataObjectTypeName="Accounts.Order"
OldValuesParameterFormatString="original_{0}"
SelectMethod="LoadByCustomerGUID"
TypeName="Accounts.OrderCollection" >
<SelectParameters>
<asp:Parameter DefaultValue="" Name="CustomerGUID" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="ods_Customer" runat="server"
DataObjectTypeName="Accounts.Customer"
OldValuesParameterFormatString="original_{0}"
SelectMethod="LoadBySequence"
TypeName="Accounts.CustomerCollection" >
<SelectParameters>
<asp:Parameter DefaultValue="0" Name="Sequence" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Code Behind:
protected void SelectID_Click(object sender, EventArgs e)
{
Accounts.Customer _customer = default(Accounts.Customer);
Accounts.CustomerCollection _customers = default(Accounts.CustomerCollection);
Accounts.OrderCollection _orders = default(Accounts.OrderCollection);
ods_Customer.SelectParameters("CustomerID").DefaultValue = textbox_CustomerID.Text;
_customers = ods_Customer.Select();
_customer = _customers(0);
ods_Orders.SelectMethod = "LoadByCustomerGUID";
ods_Orders.SelectParameters("CustomerGUID").DefaultValue = _customer.GUID.ToString;
_orders = ods_Orders.Select();
}
Related
i have to tables: Users and PrivateMessages.
Users has UserID and Username.
PrivateMessages has the coloumns PMID and Text and SenderID.
(of course it has much more but to explain the problem, its enough)
Now I have a DataSource and a method like this:
public static List<UserPM> GetAllPMsAsSender(Guid userID)
{
using (RPGDataContext dc = new RPGDataContext())
{
return (from a in dc.UserPMs where a.Sender == userID && !a.IsDeletedSender orderby a.Timestamp select a).ToList();
}
}
and bind it to the ObjectDataSource with is bound to the Grid View.
The Grid view now looks like these:
<asp:ObjectDataSource ID="odsOutcome" runat="server"
SelectMethod="GetAllPMsAsSender" TypeName="DAL.PMDAL">
<SelectParameters>
<asp:CookieParameter CookieName="UserID" DbType="Guid" Name="userID" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:GridView ID="gridOut" runat="server" AutoGenerateColumns="False"
DataSourceID="odsOutcome">
<Columns>
<asp:BoundField DataField="PMID" HeaderText="PMID" SortExpression="PMID" />
<asp:BoundField DataField="Text" HeaderText="Text" SortExpression="Text"/>
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
</Columns>
</asp:GridView>
So how I can get the Username in this field instead the UserID?
Try using join and select the user name too for your object data source and use the user name to display it instead of user id.
Refer this link How to do a join in linq to sql with method syntax?
I have an ASPxGridView, currently 11.1.7.0, which I populate with an ObjectDatasource. Everything works as expected until I use a custom editform. In another control i solved this by using the OnRowInserting attribute in the aspxgridview control, but I dont like this since it's extra work compared to using the objectdatasource.
The code looks something like this.
<dx:ASPxGridView ID="ASPxGridView1" runat="server"
ClientIDMode="AutoID"
AutoGenerateColumns="False"
KeyFieldName="UserId"
DataSourceID="ObjectDataSource1"
ClientInstanceName="grid"
onhtmleditformcreated="AsPxGridView1HtmlEditFormCreated">
<SettingsEditing PopupEditFormWidth="600" PopupEditFormModal="true" Mode="EditForm" />
<Templates>
<TitlePanel>
<dx:ASPxButton ID="New" runat="server" Text="Ny användare" ClientInstanceName="New" AutoPostBack="false">
<ClientSideEvents Click="function (s, e) { grid.AddNewRow(); }" />
</dx:ASPxButton>
</TitlePanel>
<EditForm>
First Name: <dx:ASPxTextBox ID="FirstName" runat="server" />
<dx:ASPxGridViewTemplateReplacement ID="UpdateButton" ReplacementType="EditFormUpdateButton" runat="server" />
<dx:ASPxGridViewTemplateReplacement ID="CancelButton" ReplacementType="EditFormCancelButton" runat="server" />
</EditForm>
</Templates>
<Columns>
<dx:GridViewDataTextColumn FieldName="UserId" VisibleIndex="0" />
<dx:GridViewDataTextColumn FieldName="FirstName" VisibleIndex="2" />
<dx:GridViewDataTextColumn FieldName="LastName" VisibleIndex="3" />
</Columns>
</dx:ASPxGridView>
<asp:ObjectDataSource
ID="ObjectDataSource1"
TypeName="UserData"
SelectMethod="GetItems"
UpdateMethod="ItemUpdate"
InsertMethod="ItemInsert"
DeleteMethod="ItemDelete"
runat="server">
<InsertParameters>
<asp:Parameter Name="FirstName" Type="String"/>
</InsertParameters>
</asp:ObjectDataSource>
And the UserData object
public class UserData
{
public List<TblProUserData> GetItems()
{
var tblProUserData = new TblProUserData();
tblProUserData.Fill();
return tblProUserData.List;
}
public void ItemDelete(int userId)
{ }
public void ItemUpdate()
{ }
public void ItemInsert(string FirstName)
{
// This method gets called, but the FirstName is null.
}
}
The problem is that the ItemInsert gets called, but the FirstName attribute is always null.
Is this a bug? is there a way around this? Did I miss something?
Thanks.
It is necessary to use the Two-Way data-binding technique to bind template editors with DataItem's fields:
<dx:ASPxTextBox ID="FirstName" runat="server" Text='<%#Bind("FirstName")%>' />
Based off the following question, specifying TypeName="UserData" could be causing the problem.
ObjectDataSource not calling Insert method when it has extra parameters
Try removing that from the asp:ObjectDataSource and see if the ItemInsert method works.
I am using an EntityDataSource with a FormView on VB.NET application. The FormView contains an AjaxControlToolKit TabContains with multiple tabs. Due to the fact that each tab is a naming container, Bind doesn't work properly for updating values (as discovered from reading other posts on stackoverflow). I instead have to declare UpdateParameters on my EntityDataSource. Example markup is as follows:
<asp:FormView ID="fv" runat="server" DataSourceID="eds" DataKeyNames="ID">
<EditItemTemplate>
<asp:TabContainer ID="tc" runat="server">
<asp:TabPanel ID="tp" runat="server" HeaderText="Tab 1">
<ContentTemplate>
<asp:TextBox ID="tbName" runat="server" Text='<%#Eval("Name") %>'></asp:TextBox>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
</EditItemTemplate>
</asp:FormView>
<asp:EntityDataSource ID="eds" runat="server" ConnectionString="name=NDSEntities"
DefaultContainerName="NDSEntities" EnableFlattening="False" EntitySetName="Customers"
Where="it.ID = #ID" EnableUpdate="true" EnableInsert="true">
<WhereParameters>
<asp:QueryStringParameter Name="ID" QueryStringField="ID" DbType="Guid" />
</WhereParameters>
<UpdateParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</UpdateParameters>
<InsertParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</InsertParameters>
</EntityDataSource>
This works great, until a customer is edited and their name is set to nothing (assuming in this case, a null name is allowed). The Name UpdateParameter is set to Null but the ObjectStateEntry is not set to modified for Null properties, even if previously the Entity had a value specified. As long as the name is changed to something other than Null, everything is updated correctly.
I found a workaround by putting the following code in the Updating event of the EntityDataSource.
Dim ose As ObjectStateEntry = context.ObjectStateManager.GetObjectStateEntry(action)
For Each p As Parameter In eds.UpdateParameters
ose.SetModifiedProperty(p.Name)
Next
This makes sure that each property in the UpdateParameters has its state set to modified. It works, but it seems like a hack and I can see it causing problems down the road. Is there anything else I could do?
Do you have an "Concurrency Mode" set for the entity in question? Depending on how you actually update the entity (I haven't used the EntityDataSource, but I'm guessing it internally uses the ObjectContext.Attach method), the code that creates the SQL statement, will try to update only those columns that are actually changed.
Consider the following:
void UpdatePersonEntity(int id, string firstName, string lastName)
{
Person p = new Person { Id = id };
this.Context.People.Attach(p);
p.FirstName = firstName;
p.LastName = lastName;
this.Context.SaveChanges();
}
If firstName or lastName is null, the ObjectContext would assume that it's original value hasn't been touched. This might be something you should look into. I apologize if this isn't helpful, but it might push you in the right direction.
I'm trying to display all orders placed and I have a primary accessdatasource control that has a select query to get the customer information and the orderID. I want to use the orderID value from this first query as a parameter for the secondary accessdatasource control that selects the product information of the products in the order. In plain english, I want to:- select product info from product table where orderID = ?
(where ? is the orderID value from the first query)
I have tried the <%#Eval("OrderID")%> but I get a "server tag not well formed" error, but I do get results returned when I just type the order ID in, but obviously every result (order) just contains the same product info...
<asp:Repeater ID="Repeater1" runat="server"
DataSourceID="AccessDataSource1">
<ItemTemplate>
<asp:AccessDataSource ID="AccessDataSource2" runat="server" DataFile="~/App_Data/project.mdb" SelectCommand="SELECT orderDetails.OrderID, album.Artist, album.Album, album.Cost, album.ImageURL, orderDetails.Quantity, orderDetails.Total FROM (album INNER JOIN orderDetails ON album.AlbumID = orderDetails.AlbumID) WHERE (orderDetails.OrderID = ? )">
<SelectParameters>
// Error is on this line
<asp:Parameter Name="OrderID" DefaultValue="<%#Eval ("OrderID")%>" />
</SelectParameters>
</asp:AccessDataSource>
<div class="viewAllOrdersOrderArea">
<div class="viewAllOrdersOrderSummary">
<p><b>Order ID: </b><%#Eval("OrderID")%></p>
<h4>Shipping Details</h4>
<p><b>Shipping Address: </b><%#Eval("ShippingName")%>, <%#Eval("ShippingAddress")%>, <%#Eval("ShippingTown")%>, <%#Eval("ShippingPostcode")%></p>
<h4>Payment Details</h4>
<p><b>Cardholder's Address: </b><%#Eval("CardHolder")%>, <%#Eval("BillingAddress")%>, <%#Eval("BillingTown")%>, <%#Eval("BillingPostcode")%></p>
<p><b>Payment Method: </b><%#Eval("CardType")%></p>
<p><b>Card Number: </b><%#Eval("CardNumber")%></p>
<p><b>Start Date: </b><%#Eval("StartDate")%>, Expiry Date: <%#Eval("ExpiryDate")%></p>
<p><b>Security Digits: </b><%#Eval("SecurityDigits")%></p>
<h4>Ordered items:</h4>
<asp:Repeater ID="Repeater2" runat="server"
DataSourceID="AccessDataSource2">
<ItemTemplate>
<div style="display: block; float: left;">
<div class="viewAllOrdersProductImage">
<img width="70px" height="70px" alt="<%# Eval("Artist") %> - <%# Eval("Album") %>" src="assets/images/thumbs/<%# Eval("ImageURL") %>" />
</div>
<div style="display:block; float:left; padding-top:15px; padding-right:20px;"><p><b><%# Eval("Artist") %> - <%# Eval("Album") %></b></p>
<p>£<%# Eval("Cost") %> x <%# Eval("Quantity") %> = £<%#Eval("Total")%></p></div>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
Inside of the Repeater ItemTemplate, you can create a HiddenField control and set its Value to <%#Eval("OrderID")%>. Then add a control parameter for this hidden field to the Select Parameter collection of AccessDataSource2.
<asp:HiddenField ID="HiddenField1" runat="server" Value='<%#Eval("OrderID") %>' />
<asp:AccessDataSource ID="AccessDataSource2" runat="server">
<SelectParameters>
<asp:ControlParameter ControlID="HiddenField1" PropertyName="Value" Type="Int32" />
</SelectParameters>
</asp:AccessDataSource>
Also, I think the error that you were getting may be because you used double quotes twice. Try single quotes around the server tags for the Eval statement, like I have above.
The paging is working fine here, the problem is I don't know how it works, because when I put a break point and a logger in the GetCustomers method, I found that parameters maximumRows and startRowIndex are always 0, 0.
I have no clue why StartRowIndexParameterName, and MaximumRowsParameterName are created and how they are used. If they are used in custom mode, so how to enter that mode?
Thanks
<body>
<form id="form1" runat="server">
<div>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectCountMethod="Count"
SelectMethod="GetCustomers" TypeName="Pilots.BLL.Customer">
<SelectParameters>
<asp:Parameter Name="maximumRows" Type="Int32" />
<asp:Parameter Name="startRowIndex" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:GridView ID="GridView1" runat="server" AllowPaging="true" PageIndex="0" PageSize="10"
DataSourceID="ObjectDataSource1">
</asp:GridView>
</div>
</form>
</body>
Here's a pretty thorough MSDN Article on GridView and Paging. Should be able to answer most all of your questions.
Those 2 parameters are used for custom paging on the gridview. That will be passed to SQL server to determine at what index to start the page (startRowIndex) and how many items on one gridview page (maximumRows).
The 'startRowIndex' will change depending on what the GridView.PageIndex is.
The number of rows returned from the method depends on what value set on 'maximumRows'.
It seems that I had to use EnablePaging as descried here,
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.enablepaging.aspx