Using LINQ to build a cascading list in C# - c#

I have a need to display a list of departments and sub-departments. I am loading the list of departments properly.
At this time, I have:
var deparmentList = Departments.LoadList();
var departments = new List<ListItem>(
from department in departmentList
select new ListItem {
Text = department.Name,
Value = department.Id.ToString(),
IsSelected = department.IsActive
}
);
I now need to load the list of sub-departments. Each sub-department has an Id, DepartmentId, and Name. However, I only want to get the sub-departments associated with departments that are selected. Currently, I have the following:
var subDepartmentList = SubDepartment.LoadList();
var subdepartments = new List<ListItem>(
from subdepartment in subDepartmentList
// where ?
select new ListItem {
Text = subdepartment.Name,
Value = subdepartment.Id.ToString(),
IsSelected = false
}
);
I'm not sure how to do the join or filter between the two. How do I do this in LINQ?

var selectedDepartmentSubDepartments =
from dep in departments
join subDep in subDepartmentList
on dep.Value equals subDep.Id.ToString()
where dep.IsSelected
select new ListItem {
Text = subDep.Name,
Value = subDep.Id.ToString(),
IsSelected = false
};
var subdepartments = new List<ListItem>(selectedDepartmentSubDepartments);

You can add a where clause that checks if at least one associated and 'selected' department exists:
var subDepartmentList = SubDepartment.LoadList();
var subdepartments = new List<ListItem>(
from subdepartment in subDepartmentList
where departments.Any(x => x.IsSelected &&
x.Value == subdepartment.DepartmentId.ToString())
select new ListItem {
Text = subdepartment.Name,
Value = subdepartment.Id.ToString(),
IsSelected = false
}
);

Related

Reorganize List into ListBox after adding a new Item

I have list in listbox where I want to order by a field once I added item to it:
var lstdata = (List<EmployeeAssignationModel>)lstTechToNotified.DataSource;
lstdata.Add(new EmployeeAssignationModel()
{
UserName = selectedItem.UserName,
EmpGuid = selectedItem.EmpGuid,
Name = selectedItem.Name,
Abbreviation = selectedItem.Abbreviation
});
lstTechToNotified.DataSource = null;
lstTechToNotified.DisplayMember = "Abbreviation";
lstTechToNotified.ValueMember = "UserName";
lstTechToNotified.DataSource = lstdata;
lstTechToNotified.Refresh();
So I try adding OrderBy once item is added like:
var lstdata = (List<EmployeeAssignationModel>)lstTechToNotified.DataSource;
lstdata.Add(new EmployeeAssignationModel()
{
UserName = selectedItem.UserName,
EmpGuid = selectedItem.EmpGuid,
Name = selectedItem.Name,
Abbreviation = selectedItem.Abbreviation
});
lstdata.OrderBy(x => x.Abbreviation);
lstTechToNotified.DataSource = null;
lstTechToNotified.DisplayMember = "Abbreviation";
lstTechToNotified.ValueMember = "UserName";
lstTechToNotified.DataSource = lstdata;
lstTechToNotified.Refresh();
But it just don't update, it always send item added to bottom of the list. What am I doing wrong?
OrderBy returns a new list, rather than doing the changes in place:
lstdata = lstdata.OrderBy(x => x.Abbreviation).ToList();
Try this instead.
You'll see here it returns a collection: https://msdn.microsoft.com/en-us/library/bb534966(v=vs.110).aspx

StringBuilder within IEnumerable

I have a ControlMeasure table that holds information on each control measure and a ControlMeasurepeopleExposed Table that holds a record for each person exposed in the control measure this could be 1 record or many records.
I Have a controller that populates a List view
For each item in the list, Control Measure, I would like to create a string that shows all the People at risk
e.g.
PeopleString = "Employees, Public, Others";
Ive added a foreach in the controller to show what I'm trying to do however I'm aware that this wont work.
The controller is this:
public ActionResult ControlMeasureList(int raId)
{
//Populate the list
var hazards = new List<Hazard>(db.Hazards);
var controlMeasures = new List<ControlMeasure>(db.ControlMeasures).Where(x => x.RiskAssessmentId == raId);
var cmcombined = (
from g in hazards
join f in controlMeasures
on new { g.HazardId } equals new { f.HazardId }
select new CMCombined
{
Activity = f.Activity,
ControlMeasureId = f.ControlMeasureId,
ExistingMeasure = f.ExistingMeasure,
HazardName = g.Name,
LikelihoodId = f.LikelihoodId,
Rating = f.Rating,
RiskAssessmentId = f.RiskAssessmentId,
SeverityId = f.SeverityId,
}).OrderBy(x => x.Activity).ToList();
var cmPeopleExp = new List<ControlMeasurePeopleExposed>(db.ControlMeasurePeopleExposeds).Where(x => x.RiskAssessmentId == raId);
var peopleExp = from c in cmPeopleExp
join d in db.PeopleExposeds
on c.PeopleExposedId equals d.PeopleExposedId
orderby d.Name
select new RAPeopleExp
{
RAPeopleExpId = c.PeopleExposedId,
PeopleExpId = c.PeopleExposedId,
PeopleExpName = d.Name,
RiskAssessmentId = c.RiskAssessmentId,
ControlMeasureId = c.ControlMeasureId
};
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
ControlMeasureId = t.ControlMeasureId,
HazardName = t.HazardName,
LikelihoodId = t.LikelihoodId,
Rating = t.Rating,
SeverityId = t.SeverityId,
Activity = t.Activity,
ExCM = t.ExistingMeasure,
//This section here is where I'm struggling
var PeopleString = new StringBuilder();
foreach (var p in peopleExp)
{
PeopleString.AppendLine(p.PeopleName);
{
PeopleExposed = PeopleString,
});
return PartialView("_ControlMeasureList", model);
}
I know I cant directly put this code in the controller but it does represent what I want to do.
You can't foreach within an object initializer (which is what you're trying to do when instantiating FullControlMeasureListViewModel). You can, however, use a combination of string.Join and peopleExp.Select:
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
//other props
PeopleExposed = string.Join(",", peopleExp
.Where(p => p.ControlMeasureId == t.ControlMeasureId)
.Select(p => p.PeopleExpName));
//other props
});

Set Attribute to ListItem in Linq Query

From list i am populating ListItem for dropdown list.
var list = LoadList();
var listitems = list.Select(l => new ListItem
{
Value = l.Id,
Text = l.Description
Attributes ????
}).ToList();
On the Linq query I want to add attribute. Attributes.Add() method is not accessible. Any idea?
From MSDN, the Attributes property is read only:
[BrowsableAttribute(false)]
public AttributeCollection Attributes { get; }
so you will not be able to do it using the object initialisers.
You could do this by doing something like:
var listitems = list.Select(l => { var li = new ListItem
{
Value = l.Id,
Text = l.Description
}; li.Attributes.Add(....); return li; ).ToList();

How to add the content of a combobox in a database

I want to add the content of the combobbox into my database, but it doesn't work. The content of my combobox is from the table 'Categories' who's joined with the table 'Products'. I've tried many things I have errors of conversion :
Here's my code :
Product p = new Product();
p.ProductName = txtNom.Text.Trim();
p.ProductDescription = txtDesc.Text.Trim();
p.ProductQuantityUsed = Convert.ToInt32(numQteUsed.Value);
p.ProductQuantityNew = Convert.ToInt32(numQteNew.Value);
p.CategoryID = cboCat.SelectedText.ToString();
db.Products.Add(p);
db.SaveChanges();
//Combobox
public void FillCbCategories()
{
SamsonEntities db = new SamsonEntities();
cboCat.Items.Clear();
var listCat = (from cats in db.Categories
select new CategoryDisplay()
{
CategoryID = cats.CategoryID,
CategoryName = cats.CategoryName
}).ToList();
for(var i=0;i<listCat.Count;i++)
{
cboCat.Items.Add(listCat[i]);
}
}
Judging by your comments, your combobox is not binded correctly to data you send to it.
You could try setting ValueMember and DisplayMember:
cboCat.ValueMember = "CategoryID";
cboCat.DisplayMember = "CategoryName";
in your method, like this:
public void FillCbCategories()
{
SamsonEntities db = new SamsonEntities();
cboCat.Items.Clear();
var listCat = (from cats in db.Categories
select new CategoryDisplay()
{
CategoryID = cats.CategoryID,
CategoryName = cats.CategoryName
}).ToList();
for(var i=0;i<listCat.Count;i++)
{
cboCat.Items.Add(listCat[i]);
}
cboCat.ValueMember = "CategoryID";
cboCat.DisplayMember = "CategoryName";
}

combo-box fill with the metropolitan cities at top

hi m trying fill the combo box from cities database but i wan the metropolitan cities at the top of the selection menu
i have used this approach i there any alternative??
For metros:
List<Lst_City> lstCity= new List<Lst_City>();
lstCity = new BFCommon().getCities();
lstCity[0].CityID = 474;
lstCity[0].CityNM = "Mumbai";
lstCity[1].CityID = 199;
lstCity[1].CityNM = "Delhi";
lstCity[2].CityID = 165;
lstCity[2].CityNM = "Chennai";
lstCity[3].CityID = 384;
lstCity[3].CityNM = "Kolkata";
lstCity[4].CityID = 582;
lstCity[4].CityNM = "Pune";
lstCity[5].CityID = 71;
lstCity[5].CityNM = "Bangalore";
lstCity[6].CityID = 306;
lstCity[6].CityNM = "Hyderabad";
lstCity[7].CityID = 11;
lstCity[7].CityNM = "Ahmedabad";
Dropdown binding:
ddCities.DataSource = lstCity;
ddCities.DataTextField = "CityNM";
ddCities.DataValueField = "CityID";
ddCities.DataBind();
ddCities.Items.Insert(0, new ListItem("Select One", string.Empty));
Query:
public List<Lst_City> getCities()
{
List<Lst_City> temp = (from e in objCommonDataContext.Lst_Cities
where e.inUse == true
select e).ToList();
return temp;
}
and the combo box in designer
<div class="row">
<label>
City :</label>
<ajaxToolkit:ComboBox ID="ddCities" runat="server" AutoPostBack="False"
DropDownStyle="DropDownList"
AutoCompleteMode="SuggestAppend"
CaseSensitive="False"
CssClass=""
ItemInsertLocation="Append" Width="380px"></ajaxToolkit:ComboBox>
am achieving the purpose but it doesn't seems ideal since hard coded and also entries are repeated
It seems from your code, all the cities are in a table.
My suggestion is:
Add a new column may be IsMetropolital
List<Lst_City> temp = (from e in objCommonDataContext.Lst_Cities
where e.inUse == true && e.IsMetropolital==false
select e).ToList();
List<Lst_MetroCity> tempMetro = (from e in objCommonDataContext.Lst_Cities
where e.inUse == true && e.IsMetropolital=true
select e).ToList();
List<Lst_City> lstCity= new List<Lst_City>();
foreach(var t in tempMetro)
{
// Add cities to the lstCity
}
foreach(var t in temp)
{
// Add cities to the lstCity
}
Now finally populate set the datasource of the dropdown with lstCity as you have done.

Categories

Resources