How can I get the count in linq? - c#

I have table called products with columns:
productid ,
productname,
productprice
categoryid
My problem is I want to get the number of products depending on product name along with details. I want to show the data in DataGridView. How can I know the number of products for a single product name like below?
productid productname productavailable productprice
--------------------------------------------------------------------------
1 product A 2 products(product A) 100
2 product B 5 Products(product B) 200
Like the above table I have to display in DataGridView. I am using LINQ and C# and my DbContext name is tsgdbcontext.

Use GroupBy with a key that contains your grouping properties. Then select out the key properties along with the count of each from the grouping.
var query = tsgdbcontext.Products
.GroupBy(p => new {
p.ProductId,
p.ProductName,
p.ProductPrice
})
.Select(g => new {
g.Key.ProductId,
g.Key.ProductName,
g.Key.ProductPrice,
Available = g.Count()
});

Not sure I am understanding exactly + making some assumptions but here is an example linq query that produces a count based on some arbitrary selection criteria (id=2 and price greater than 100)...
int count = (from p in tsgdbcontext.Products
where p.productid == 2 && p.productprice > 100
select p).Count();

Related

EF duplicate values in secondary table

I'm developing a web application using Entity Framework.
I need do a select and pass values for an Ilist but it's returns duplicate values.
IQueryable<establishmentInfo> filter = (from x in db.establishments
join t in db.establishment_categories on x.id equals t.establishment
join q in db.categories on t.category equals q.id
where (x.name.ToUpper().Contains(search.ToUpper()))
select new establishmentInfo
{
id = x.id,
name = x.name,
id_category = q.id,
category = q.name,
});
IList<establishmentInfo>establishments = filter.ToList();
Establishment table
id name email
---------------------------
1 AAA a#a.com
2 BBB b#b.com
Establishment_categories
id establishment category
-------------------------------
1 1 1
2 1 2
3 2 1
Categories
id name
---------------------
1 alpha
2 beta
The problem is that return 2 establishments, one with category 1 and other with category 2. I need remove one of these.
Can anyone help?
As #NetMage said,your linq statement should return two values that are not repeated.
We can see that there are two records with establishment set to 1 in your Establishment_categories table. You can check your establishments. The id_category should be 1, the category should be alpha, the other should be id_categoryis 2, and the category should be beta.
You can see below image:
If you only want to get the first data of establishments, you can write the code as follows:
IQueryable<Establishment> filter = (from x in _context.Establishments
join t in _context.Establishment_Categories on x.Id equals t.EstablishmentId
join q in _context.Categories on t.CategoryId equals q.Id
where x.Name.ToUpper().Contains(search.ToUpper())
select new Establishment
{
Id = x.Id,
Name = x.Name,
CategoryId = q.Id,
CategoryName = q.Name,
}).Take(1);
List<Establishment> establishments = filter.ToList();
Result:
By the way, assuming that there are duplicates in your returned data, you can add the .Distinct() method after your linq to remove duplicates.

Get list of items where their ID is equal to some Values - linq c#

Here is a query:
from order in db.tblCustomerBuys
where selectedProducts.Contains(order.ProductID)
select order.CustomerID;
selectedProducts is a list containing some target products IDs, for example it is { 1, 2, 3}.
The query above will return customerIDs where they have bought one of the selectedProducts. for example if someone has bought product 1 or 2, its ID will be in result.
But I need to collect CustomerIDs where they have bought all of the products. for example if someone has bought product 1 AND 2 AND 3 then it will be in result.
How to edit this query?
the tblCustomerBuys are like this:
CustomerID - ID of Customer
ProductID - the product which the customer has bought
something like this:
CustomerID ProdcutID
---------------------------
110 1
110 2
112 3
112 3
115 5
Updated:
due to answers I should do grouping, for some reason I should use this type of query:
var ID = from order in db.tblCustomerBuys
group order by order.CustomerID into g
where (selectedProducts.All(selProdID => g.Select(order => order.ProductID).Contains(selProdID)))
select g.Key;
but it will give this error:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
The updated query is the general LINQ solution of the issue.
But since your query provider does not support mixing the in memory sequences with database tables inside the query (other than Contains which is translated to SQL IN (value_list)), you need an alternative equivalent approach of All method, which could be to count the (distinct) matches and compare to the selected items count.
If the { CustomerID, ProductID } combination is unique in tblCustomerBuys, then the query could be as follows:
var selectedCount = selectedProducts.Distinct().Count();
var customerIDs =
from order in db.tblCustomerBuys
group order by order.CustomerID into customerOrders
where customerOrders.Where(order => selectedProducts.Contains(order.ProductID))
.Count() == selectedCount
select customerOrders.Key;
And if it's not unique, use the following criteria:
where customerOrders.Where(order => selectedProducts.Contains(order.ProductID))
.Select(order => order.ProductID).Distinct().Count() == selectedCount
As your question is written, it is a bit difficult to understand your structure. If I have understood correctly, you have an enumerable selectedProducts, which contains several Ids. You also have an enumeration of order objects, which have two properties we care about, ProductId and CustomerId, which are integers.
In this case, this should do the job:
ver result = db.tblCustomerBuys.GroupBy(order => order.CustomerId)
.Where(group => !selectedProducts.Except(group).Any())
.Select(group => group.Key);
What we are doing here is we are grouping all the customers together by their CustomerId, so that we can treat each customer as a single value. Then we are treating group as a superset of selectedProducts, and using a a piece of linq trickery commonly used to check if one enumeration is a subset of another. We filter db.tblCustomerBuys based on that, and then select the CustomerId of each order that matches.
You can use Any condition of Linq.
Step 1 : Create list of int where all required product id is stored
Step 2: Use Any condition of linq to compare from that list
List<int> selectedProducts = new List<int>() { 1,2 } // This list will contain required product ID
db.tblCustomerBuys.where(o=> selectedProducts .Any(p => p == o.ProductID)).select (o=>o.order.CustomerID); // This will return all customerid who bought productID 1 or 2

Linq count products for a specific customer

hi I have this query that count all the products sold and now I want to change it so it counts the amount of products for a particular customer. Anyone can help me please? Tables= table customer one2many transactions one2many transactionitems many2one product many2one producttype
var query = from product in cse.tblTransactionItems
group product by product.tblProduct.Description into g
select new { ProductId = g.Key, totalUnitsSold = g.Count() };
You could consider grouping by multiple columns.
var query = from product in cse.tblTransactionItems
group product by new
{
product.tblProduct.Description,
product.tblProduct.Customer // put the customer here.
} into g
select new
{
Product = g.Key.Description,
Customer = g.Key.Customer,
totalUnitsSold = g.Count()
};
This way the totalUnitsSold is a total for a specific customer and product.
Note: If your customer is in another table, you'll need to join first. The above simply assumes customer to be part of your existing table.

LINQ - ENTITY: Need to return a list of count of rows in ANOTHER table

I have a system with a table PRODUCTS and FAULTS. Each product can have a number of faults (the fault table has a foreign key ProductID). I need to get a list of aproximately ten products with the most number of faults. I tried the following but it doesn't seem to be work (the fields that i need are the product name, price, id and the number of faults):
return (from p in Entity.Products
join f in Entity.Faults
on p.ProductID equals f.ProductID
group f by new { f.ProductID, p.Name, p.Price } into product
select new CountFaultView()
{
ProductID = product.Key.ProductID,
Name = product.Key.Name,
Price = product.Key.Price,
FaultsCount = product.Key.Name.Count()
}
).OrderByDescending(x => x.FaultsCount).Take(10);
}
I am TRYING to count the number of times that the name is displayed but obviously I seem to be getting something wrong ;o

Ranking. Linq to sql question

I have a table of orders made by persons:
Orders
{
Guid PersonId,
int Priority,
Guid GoodId
}
Priority is some integer number. For example:
AlenId 1 CarId
DianaId 0 HouseId
AlenId 3 FoodId
DianaId 2 FlowerId
I want to retrieve highest priority orders for each person:
AlenId 1 CarId
DianaId 0 HouseId
In T-SQL I'll use ranking, how can I get the same result in Linq-2-Sql ?
Thank you in advance!
Something like this:
var query = from order in context.Orders
orderby order.Priority
group order by order.PersonId into personOrders
select personOrders.First();
I believe that should work, but I don't know how well-defined it is, in terms of the ordering post-grouping. This would also work, although it's slightly uglier:
var query = from order in context.Orders
group order by order.PersonId into personOrders
select personOrders.OrderBy(order => order.Priority).First();
Or using just dot notation:
var query = context.Orders
.GroupBy(order => order.PersonId)
.Select(group => group.OrderBy(order => order.Priority)
.First());

Categories

Resources