I'm databinding a radiobuttonlist with a LINQ query like so:
var query = from m in Db.Udt_Menu
orderby m.Name
select m;
this.radMenuSelection.DataValueField = "menuID";
this.radMenuSelection.DataTextField = "name";
this.radMenuSelection.DataSource = query;
this.radMenuSelection.DataBind();
However, when i want to update the record I need to set the selectedindex of the radiobutton to a value from the database. There is a table called udt_PageMenuSelection which has a column called menuID which is a foreign key to udt_Menu.menuID.
When i want to update an existing record, how do i set the selectedindex of the radiolist to the value equal to udt_PageMenuSelection.menuID ?
Do I need to do an additional query?
Thanks
higgsy
I think I understand the structure, and yes it seems the best way to do things; the udt_Menu entity would have a relationship to udt_PageMenuSelection as a one to many relationship, and you could use LoadWith<> to load those, but that is overkill since I think you are talking loading one record. It would be best to just query it separately.
HTH.
Related
I have inherited an ASP.NET website built on NHibernate, with which I have no experience. I need to add a calculated field based on a column in a related table to an existing query. In SQL, this would be done easily enough using a correlated subquery:
select
field1,
field2,
(select count(field3) from table2 where table2.table1ID = table1.ID) calc_field
from
table1
where
[criteria...]
Unfortunately, of course, I can't use SQL for this. So in reality, I have three related questions:
What is the best way to trace through the web of interfaces, base classes, etc used by NHibernate in order to pinpoint the object where I need to add the field?
Having located that object, what, if anything, has to be done besides adding a public property to the object corresponding to the new field?
Are there any NHibernate-specific considerations with regard to referencing a related object in a query?
Here is the existing code that performs the search:
public INHibernateQueryable<C> Search(ISearchQuery query, string sortField)
{
_session = GetSession();
var c = _session.Linq<C>();
c.Expand("IP");
c.Expand("LL");
c.Expand("LL.Address");
c.Expand("LL.Address.City");
c.Expand("LL.Address.City.State");
c.Expand("LL.Address.City.County");
c.Expand("CE");
c.Expand("IC");
c.Expand("AR");
c.Expand("ER");
c.Expand("Status");
var res = _SearchFilters
.Where(x => x.ShouldApply(query))
.Aggregate(c, (candidates, filter) => (INHibernateQueryable<C>) filter.Filter(candidates, query));
res = SortSearch(res, sortField);
return res;
}
I appreciate any advice from experienced Hibernators.
Thanks,
Mike
If you are only interested in returning a query containing a computed value, you can still call a stored procedure in NHibernate and map the results to a POCO in the same way as you map a table for CRUD operations; obviously read-only instead of updatable.
Have a look at the ISession.CreateSQLQuery method; I can post an example from one of my projects if you need one.
I'm trying to populate the checked values on a checkboxlist based upon a LINQ query. But I am having trouble figuring out how to do this.
I have an Enum called UserRoles and on page load I bind the checkbox list to the enum values, and descriptions.
uRoles.DataSource = RiseBi.Enumeration.GetEnumDescriptions(GetType(UserTypes))
uRoles.DataTextField = "Value"
uRoles.DataValueField = "Key"
Next to get the user roles:
Public Shared Function GetAllUserRoles(ByVal EID As Integer) As IQueryable(Of RiseDB.UserRole)
Dim DB As New RiseDB.RiseDBContainer
Dim tmp = (From p In DB.Users Where p.Id = EID).First
Return tmp.UserRoles
End Function
What would be the best way to populate the checkboxes for that particular user that matches the roles?
I was thinking just a loop for each value in UserRoles and where they match check it, but there has to be a simpler way, no?
in msdn CheckBoxList Class
To determine the selected items in the CheckBoxList control, iterate through the Items collection and test the Selected property of each item in the collection.
so only loop for checking items
Say I have an Employee table. Each Employee has a unique id. One of the columns in the table is ManagerId, which corresponds to another Employee. When binding an Employee's data to a GridView, I want to display the Manager's name, not their Id. If I had a lookup table for Mangers I could just do <%# Eval("lu_Managers.ManagerName") %>, but I don't have such a table, nor do I want to make one/keep track of it/update it everytime a new manager is added or removed.
Currently in the OnRowDataBound I call e.Row.Cells[1].Text = getFullNameFromEmployeeId(Convert.ToInt32(e.Row.Cells[1].Text)); which seems fairly messy to me.
Is there a way to do this without using the codebehind? Or would that be less efficient than what I have now?
You need to join the Employee table again for the manager
SELECT
Employee.*,
Manager.FirstName As ManagerName
FROM
tblEmployee As Employee
JOIN tblEmployee As Manager
ON Employee.ManagerID = Manager.pkEmployeeID
EDIT:
Which can be easily translated into LINQ:
var q =
from employee in db.tblEmployee
join manager in db.tblEmployee
on employee.ManagerID equals manager.pkEmployeeID
select new
{
Employee = employee,
ManagerName = manager.FirstName
};
OK, if there a unary relationship setup? If a relationship, Employee would have an Employee property that points to that manager, so you could reference with Employee.EmployeeName. Otherwise, if no explicit navigation property, you would have to use a query from code-behind.
HTH.
I have a dropdown list (FK) which I would like to set and display a default value based on a login userid. Can you please tell me how to do it? I only want to affect the dropdown filter that appear at the top above the Gridview.
Thanks
Nikos
If you only want this functionality in the DropDown list that appears in the Filter Criteria section, just modify the URL by adding the QueryString parameters you would like to filter by. The DynamicFilter will pick up the values from the QueryString and set the DropDown lists accordingly. (fyi. this is the same functionality that the ForeignKey.ascx FieldTemplate provides)
It would be nice if there was a better way to actually create this URL (instead of using string), but as of right now, any solution I provide is probably going to break in a subsequent version.
example (in page_load)
Response.Redirect("~/Employees/List.aspx?ReportsTo=1234");
Is this a universal change, or just for one foreign key relationship?
Assuming it is for just one foreign key relationship, you could create a new FieldTemplate, to be used just for that relationship. The New FieldTemplate would be a copy of the default "ForeignKey" FieldTemplate. In the New FieldTemplate modify the OnDataBinding (or Page_PreRender) event to set the "default value" of the DropDownList.
Then, to force the New FieldTemplate to be used for that relationship, you would need to use the System.ComponentModel.DataAnnotations.UIHint attribute on the member of your Entity Class that represents that foreign key relationship. (links below)
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute.uihint.aspx
or http://www.asp.net/learn/3.5-SP1/video-291.aspx (around 07:30 mins)
For a little help, you could take a look at the DynamicData Futures release on CodePlex. Specifically the "Populate Insert templates with values from filters" section. http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14475
I have figured out a workaround, but am open to a more elegant solution.
I edited the FilterUserControl.ascx.cs by inserting the following line in the Page_Init after PopulateListControl(DropDownList1);
DropDownList1.SelectedIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByText("Bob")); // Username is hardcoded just for test
This seems to work but I would prefer using the custom Partial Entity Class with metadata to solve this if possible.
I have solved this in an application I am working on, in your insert view template code behind:
In ItemCreated event for the details view:
foreach (DetailsViewRow row in DetailsView1.Rows)
{
foreach (Control ctl in row.Controls)
foreach (Control c in ctl.Controls)
foreach (Control x in c.Controls)
{
if (x.ClientID.Contains("tblName"))
{
foreach (Control y in x.Controls)
{
if (y.ClientID.Contains("DropDownList"))
{
ddl = y as DropDownList;
ddl.SelectedValue = Convert.ToString(UserId);
ddl.Enabled = false;
}
}
}
}
}
With this code, when a user is logged in and they go to insert some entity (tblName) the drop down list (fk to userId) is already selected and disabled.
I have a news portal.
For this portal I have a database with a "News" table and with the following columns
(NewsID, CategoryID, NewsTitle, NewsText, DateAdded, ImagePath, TotalRead, NewsType, isActive)
I use dataset files (.xsd) and for this one, I have a query that returns the last 3 days' news into a custom class that I coded, named HHNews.
HHNews Class has a function that returns a strongly-typed datatable that includes the results of the query I mention above.
The home page has different sections for news.. these are;
- Headlines (5 items)
- Sub-headings (4 items)
- Last 5 news items for each of the news categories...( categories are like; sports, local news, economics,
For the home page, I retrieve the datatable returned from the class. Now I want to query this datatable and build the sections I mention above.. e.g.
if my datatable is called "dt", then is there a way to sql-like query this dt such as "select TOP(5) NewsID, NewsTitle, NewsText from dt where NewsType = 0" -- 0 representing the headline ?
Absolutely. You can use LINQ as Dave Cluderay mentioned. To retrieve your headlines, for example, you could run:
var myDataTable = dt.AsEnumerable();
var headlines = myDataTable.Where(t => t.NewsID == 0).Take(5);
You can use LINQ to DataSet if you're in .NET 3.5.
If you aren't in .NET 3.5, you can create a DataView based on the DataTable object and then set the RowFilter property on the DataView. For example:
DataView myDV = new DataView(dt);
myDV.RowFilter = "NewsType = 0";
You can then catch only the first 5 rows in your DataView.
You can use the default view to filter the datatable like so:
dt.DefaultView.RowFilter = "NewsType = 0";
Not sure how you would get the top 5!?
If you're not in 3.5 you could use a simple for loop to get the top 5 rows after sorting the table.
There is a Select method on the Datatable, dont think there is a way to limit the amount returned. I like the LINQ way, but just an alternative....but the limit might count this out.
dt.Select("NewsType = 0");