I'm having problems with getting selected items in a select-list.
Product product = _pr.GetProducts().ByProductID(productID).First();
product.Categories.Load();
ICollection<Category> allCategories = _cr.GetCategories().ToList();
List<SelectListItem> Categories = (from category in allCategories
select
new SelectListItem
{
Selected = product.Categories.Contains(category),
Value = category.CategoryID.ToString(),
Text = category.Categoryname
}).ToList();
Categories return 4 items, and selected is false on all....... If I hover "product.Categories" there are 3 items there, which is correct.... but somehow it doesnt get set to true.
What might be wrong?
/M
The overload of Contains() that you're using is going to use the default object comparison, which will only match the exact same instance unless you've overridden Equals() and GetHashCode(). One option is to create a custom CategoryEqualityComparer and pass it to this overload of Contains(). Or, you could just join the categories on ID:
Product product = _pr.GetProducts().ByProductID(productID).First();
product.Categories.Load();
ICollection<Category> allCategories = _cr.GetCategories().ToList();
List<SelectListItem> Categories = (
from category in allCategories
join pc in product.Categories
on category.CategoryID equals pc.CategoryID into j
select
new SelectListItem
{
Selected = j.Any(),
Value = category.CategoryID.ToString(),
Text = category.Categoryname
}).ToList();
I see that you set 'allCategories' to a _cr.GetCategories collection - are you sure the product contains categories from that collection? It looks like your Categories field doesn't contain any of the product categories. Can you post what is in each collection?
Related
In table I have 4 Columns GroupName, Display, Value and ID
How can I just show a specific data in display. I only want to show some of the groupNames Data
for example I only want to show Groupname = company and display = Forbes
Here's my linq
sample = (from c in smsDashboardDBContext.CodeDefinitions
orderby c.Display ascending
select new CodeDefinitionDTO
{
GroupName = c.GroupName,
Display = c.Display,
Value = c.Value,
Id = c.Id
}).ToList();
You can add a where statement in the query.
where c.GroupName == "company" && c.Display == "Forbes"
I only want to show some of the groupNames Data for example I only want to show Groupname = company and display = Forbes
Before the ToList, use a Where to keep only those items that you want to show:
var company = ...
var forbes = ...
var result = smsDashboardDBContext.CodeDefinitions
.OrderBy(codeDefinition => codeDefintion.Display)
.Select(codeDefinition => new CodeDefinitionDTO
{
Id = codeDefinition.Id,
GroupName = codeDefinition.GroupName,
Display = codeDefinition.Display,
Value = codeDefinition.Value,
})
.Where(codeDefinition => codeDefition.GroupName == company
&& codeDefintion.Display == forbes);
In words:
Order all codeDefinitions that are in the table of CodeDefintions by ascending value of property codeDefintion.Display.
From every codeDefinition in this ordered sequence make one new CodeDefinitionDTO with the following properties filled: Id, GroupName, Display, Value
Frome every codeDefintion in this sequence of CodeDefinitionDTOs, keep only those codeDefinitions that have a value for property GroupName that equals company and a value for property Display that equals forbes.
There is room for improvement!
Suppose your table has one million elements, and after the Where, only five elements are left. Then you will have sorted almost one million elements for nothing. Consider to first do the Where, then the Order and finally a Select.
In LINQ, try to do aWhere as soon as possible: all following statements will have to work on less items
In LINQ, try to do a Select as late as possible, preferrably just before the ToList / FirstOrDefault / ... This way the Select has to be done for as few elements as possible
So first the Where, then the OrderBy, then the Select, and finally the ToList / FirstOrDefault, etc:
var result = smsDashboardDBContext.CodeDefinitions
.Where(codeDefinition => ...);
.OrderBy(codeDefinition => codeDefintion.Display)
.Select(codeDefinition => new CodeDefinitionDTO
{
...
});
I have a page that contains a list a companies. Each company is appart of a group, like such:
But here's the catch, groups can be disabled, if they are, that would not change the display of the list but it does have an impact on my edition page.
As you can see, there is a DropDownList containing my groups. But if a group is disabled it does not show up on the list because I retrieve said list like such:
public IEnumerable<SelectListItem> ListGroupEnabled()
{
List<SelectListItem> X = _entities.Groups.Where(p => p.IsEnabled).ToList().Select(c => new SelectListItem { Value = c.GroupId.ToString(), Text = c.Name }).ToList();
return X;
}
But here's what I wish to achieve:
If I were to edit a company that was appart of a disabled group, I still want that group (and only that group) to appear in the DDList among enabled groups.
This is for the sake of logic, it wouldn't make sense to simply not have the group a company is appart off in its list.
How may I change the code I showed up above in order to keep the group the company is appart off in my list?
Hello SelectListItem have Properties such as Disabled you can set it before send. referrence
fix your code at below.
public IEnumerable<SelectListItem> ListGroupEnabled()
{
List<SelectListItem> X = _entities.Groups.Select(c => new SelectListItem { Value = c.GroupId.ToString(), Text = c.Name , Disabled = c.IsEnabled }).ToList();
return X;
}
You need to pass in the current group id and include that in your where clause:
public IEnumerable<SelectListItem> ListGroupEnabled(int? currentGroupId = null)
{
return _entities.Groups.Where(
p =>
p.IsEnabled ||
(currentGroupId.HasValue && p.GroupId == currentGroupId.Value)
).Select(c => new SelectListItem { Value = c.GroupId.ToString(), Text = c.Name }).ToList();
}
You also don't need to call ToList before selecting. That actually makes the query less optimized as without that, Entity Framework can just select the columns it needs (GroupId and Name).
public ActionResult List_of_Winners(int id=0)
{
var winners = (from cat in db.Events_Category_tbl
join can in db.Candidates_Info_tbl
on cat.events_category_id equals can.events_category_id
where cat.events_info_id == id
select new Candidates
{
events_category_name = cat.events_category_name,
candidates_fullname = can.candidates_fullname,
candidates_info_id = can.candidates_info_id,
events_category_id = cat.events_category_id,
no_of_votes = can.no_of_votes.Value
}).OrderBy(x => x.no_of_votes).Distinct();
return PartialView(winners);
}
I have 2 tables, the Events_Category_tbl & Candidates_Info_tbl then in one category there are many candidates registered. Then, what I want to do is that I need to get only the highest votes in the category. And this serve as the winner of the category.
My Candidates table looks like this:
candidates_info_id,
candidates_fullname,
events_category_id,
no_of_votes
My Category table looks this way:
events_category_id,
events_category_name
Then, I want a result in my query that in one category it has one winner of the candidates the one got the highest votes.
How am I gonna do that?
Above is my code.
Hi I am trying to convert a a LINQ query result into a list of objects and I seem to be doing something wrong because I can not acces the properties of each object.Here is my code:
List<Object> productList = new List<Object>();
var products = (from p in Products
join s in SubCategories on p.SubcatId equals s.SubCatId
join b in Brands on p.BrandId equals b.BrandId
select new
{
Subcategory = s.SubCatName,
Brand = b.BrandName,
p.ProductName,
p.ProductPrice
}).Where(x => x.Subcategory == subcategory);
foreach (var product in products)
{
productList.Add(product);
}
foreach (var produs in productList){
Console.WriteLine(produs.ProductName);
}
When I try to do this I get an error that says:
Object does not contain a definion for ProductName
The same goes for all the other fields two
Aldo if I try and do this:
Console.WriteLine(produs);
I get tables with the data for each field
I have run this for tests on LINQPAD and it also does not work in visual studio.What am I doing wrong?
This is the problem:
List<Object> productList = new List<Object>();
You're declaring it as a List<object>, which means when you later write this:
foreach (var produs in productList)
Then produs is implicitly typed as object.
The simplest approach would be just to use ToList() instead of copying the results to a list yourself:
var products = (from p in Products
join s in SubCategories.Where(x => x.SubCatName == subcategory)
on p.SubcatId equals s.SubCatId
join b in Brands on p.BrandId equals b.BrandId
select new {
Subcategory = s.SubCatName,
Brand = b.BrandName,
p.ProductName,
p.ProductPrice
}).ToList();
Note that I've moved the subcategory name filter as early as possible - there's no need to do it after the join. The ToList() call at the end will mean the result is a List<T> where T is your anonymous type.
Then you can use:
foreach (var product in products)
{
Console.WriteLine(produs.ProductName);
}
use
List<Product> productList = new List<Product>();
instead of
List<Object> productList = new List<Object>();
where Product is the unit of Products
A List of Object means that you only get the methods contained within an object. You should do something like:
List<Product> productList = new List<Product>();
Just as a note you can also do:
productList = products.ToList<Product>();
instead of iterating over the list and adding each element. (Linq does this for you implicitely).
NOTE: This is assuming that you change your query select to select new Product { ... }
This will then allow you to use List<Product> productList so that you can pass your Product list to other methods etc.
Let's say I have a list of Boxes and in a box you can have multiple items.
Box (id)
Items (id, boxId)
I'm trying to build a linq to entity query that can return all the boxes that contains ALL specified items.
List<Box> FindBoxContainingAllSpecifiedItems(List<int> itemIds)
{
var q = from box in ctx.Boxes
where ???
}
Thanks for the help
It depends on the implementation of boxes. But lets for the moment say it has a property Items with the type IEnumerable<int>. In that case you could use the Intersect extension method to see if the items are all accounted for
var q = from box in ctx.Boxes
where box.Items.Intersect(itemIds).Count() == itemIds.Count;
Here is what I have found thanks to JaredPar contribution.
List<Location> FindLocationContainingAllItems(List<int> itemIds)
{
var itemQuery = from item in ctx.Items
select item;
// Workaround the Where In Clause (http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0)
itemQuery = itemQuery.Where(BuildContainExpression<Items, int>(i=> i.Id, itemIds));
int itemCount = itemIds.Count();
var locQuery = from loc in ctx.Locations
from box in loc.Boxes
where (from items in box.Items select items).Intersect(itemQuery).Count == itemCount
select loc;
return locQuery.ToList();
}