Use orderby using linq query - c#

I have 4 column, facilities0id, name, date, Quantity. I have few problem here
How to use orderby based on the quantity. I wan to find top 3 row. Anyone can help, thanks
DataClassesDataContext db = new DataClassesDataContext();
var query = from p in db.Facilities
join v in db.Reservations on p.facilities_id equals v.facilities_id
join c in db.Reservation_Details on v.reservation_id equals
c.resevation_id
where SqlMethods.Like(c.date, "%" + DropDownList1.Text + "%")
select new
{
p.facilities_id,
p.name,
c.date,
Quantity = p.Reservations.Count()
};
GridView1.DataSource = query.GroupBy(x => x.facilities_id)
.Select(g => g.First())
.ToList();
GridView1.DataBind();
int totalRowsCount = GridView1.Rows.Count;
Label2.Text = DateTime.Now.ToShortDateString();
Label3.Text = totalRowsCount.ToString() + " record(s)";
Label4.Text = DropDownList1.Text;
Data in my database
facilities_id name date Quantity
F001 cc 12-12-2014 3
F002 vv 12-12-2014 2
F003 gg 12-12-2014 1
F004 bb 12-12-2014 5
Here is my expected output
facilities_id name date Quantity
F004 bb 12-12-2014 5
F001 cc 12-12-2014 3
F002 vv 12-12-2014 2

Use OrderByDescending to sort your records by Quantity in descending order,then Take first 3 records:
query.GroupBy(x => x.facilities_id)
.Select(g => g.First())
.OrderByDescending(x => x.Quantity)
.Take(3)
.ToList();

Use For Descending "OrderByDescending"
.OrderByDescending(x => x.Quantity);
Use For Ascending "OrderBy"
OrderBy(x => x.Quantity);

you need to first use order by descending for column quantity and then take first three rows

Related

How to return number of rows inserted each month from SQL using EF C#

I have a customers table and I want to return count of rows inserted each month or Customers registered each month. The following code returns only month and record count but I want to record 0 if say for Jan no customers where registered. Thank you.
The following code returns:
Month 2 Count 15
Month 5 Count 11
Month 9 Count 82
I also want to return
Month 1 count 0
Month 3 count 0
so on..
My code:
var query = (from customers in context.customers
group customers by customers.RegisterDateTime.Month into g
select new
{ Month = g.Key, Count = g.Count() }
).ToList();
foreach (var data in query)
{
Console.WriteLine( "Month "+ data.Month +" Count "+ data.Count);
}
var query = (from m in Enumerable.Range(1, 12)
join c in context.customers on m equals c.RegisteredDateTime.Month into monthGroup
select new { Month = m, Count = monthGroup.Count() }
).ToList();
I assume that you want the range from the lowest month and the highest month.
I see no possiblity (but maybe there is?) to do it inside your query directly. I would add the "0" after the query to fill the gaps between the range with zeros.
So I would add the following code line after your query:
var lowestKey = result.Min(x => x.Month);
var highestKey = result.Max(x => x.Month);
query = query.Union(
Enumerable.Range(lowestKey, highestKey - lowestKey)
.Where(e => !result.Any(r => r.Month == e))
.Select(s => new { Month = s, Count = 0 })
).OrderBy(o => o.Month).ToList();
Since I don't have your complete code, this query maybe need some adjustment.
If you need another range, than you can simple change it.
My complete example look like this:
static void Main(string[] args)
{
// Initialize the list
var result = new []
{
new { Month = 2, Count = 15 },
new { Month = 5, Count = 11 },
new { Month = 9, Count = 82 }
}.ToList();
// Generate a List with 0 in Range
var lowestKey = result.Min(x => x.Month);
var highestKey = result.Max(x => x.Month);
result = result.Union(
Enumerable.Range(lowestKey, highestKey - lowestKey)
.Where(e => !result.Any(r => r.Month == e))
.Select(s => new { Month = s, Count = 0 })
).OrderBy(o => o.Month).ToList();
foreach (var data in result)
{
Console.WriteLine("Month " + data.Month + " Count " + data.Count);
}
Console.ReadKey();
}
Hope it helps,
var query = (from customers in context.customers
group customers by customers.RegisterDateTime.Month into g
select new
{ Month = g.Key, Count = g.Count(x=>x!=null) }
).ToList();

Linq GroupJoin add default entries

var storeIds = repository.Get<Store>()
.Select(s => s.Id)
.ToList();
var storeReceipts = repository.Get<Receipt>()
.Where(r => DbFunctions.TruncateTime(r.LogDate) == today)
.GroupBy(r => r.StoreId)
.Select(g => new { Id = g.Key, Sales = g.Sum(r => r.TotalPrice) })
.GroupJoin(storeIds, x => x.Id, s => s, (x, s) => x ?? new { Id = s, Sales = 0 });
Basically I want the GroupJoin to add an entry to the sequence for any Store that doesn't have Receipt records.
My syntax above with the ?? doesn't compile (even if it did I am not sure its correct).
If you want to join the two tables, you may want to try this.
var storeSales = from s in repository.Get<Store>()
join r in repository.Get<Receipt>() on s.Id equals r.StoreId into g
select new {
StoreId = s.Id,
Sales = g.Sum(x => (decimal?)x.TotalPrice) ?? 0
};
It selects from the Stores first, so that you will get an entry for each store. It will next join the Receipts by matching store id into a group g that joins the two.
That allows the selection of your output shape, one item per store. In this case, the Id of the store as StoreId, and the sum of the TotalPrice values for each receipt as the Sales are selected.
If there were no receipts for a store, this sum will end up being 0.

Convert SUM / CASE WHEN / GROUP BY SQL query into LINQ

I am having a VERY hard time converting my simple SQL query to LINQ...
SELECT Id
,Location
,SUM( CASE
WHEN TransactionType = 'Out' THEN [Quantity] * -1
ELSE Quantity
END) AS StockQuantity
FROM Transactions
WHERE Id = 123
GROUP BY Id, Location
here is my best WRONG attempt...
var result = db.Transactions
.Where(r => r.Id == 123)
.GroupBy(r => r.Id, r => r.Location)
.Select(group => new
{
Id = r.Id,
Location = r.Location,
Quantity = sum(r.TransactionType == 2 ? r.Quantity * -1 : r.Quantity),
});
Thanks in advance
You are not using your grouped values. Your query should be like:
var result = db.Transactions
.Where(r => r.Id == 123)
.GroupBy(r => new { r.Id, r.Location} )
.Select(grp => new
{
Id = grp.Key.Id,
Location = grp.Key.Location,
Quantity = grp.Sum(t=> t.TransactionType == 2 ? t.Quantity * -1 : t.Quantity),
});
I would also use a different variable name than group in projection (Select) since it is a contextual keywords (with query expression)

SQL to LINQ Converter

I have a SQL and having a hard time to convert it to LINQ. Are there any other tools that can convert SQL to LINQ? I heard Linqer and tried it but it doesn't allow you to query on the Junction/Join Table of a Many-to-Many relationship tables. In any case here's the SQL that I need to convert to LINQ or even lambda.
SELECT A.*
FROM
( SELECT TOP 10 T2.ID,
T2.Name,
SUM(T1.Column1 + T1.Column2 + T1.Column3) AS Total
FROM POS.dbo.Table1 T1
INNER JOIN POS.dbo.Table2 T2 on T2.ID = T1.ID
WHERE T2.ID IN
(
SELECT ID FROM POS.dbo.Table3 WHERE [Id] = 1
)
AND [Date] BETWEEN '2011-11-09 00:00:00' AND '2011-11-09 23:59:59'
GROUP BY T2.ID, T2.Name
ORDER BY Total DESC
) A
ORDER BY Name ASC
Here is my first attempt:
var query = db.Table1
.Include(e => e.Table2)
.Where(x => x.Date >= '2011-11-09 00:00:00'
&& x.DateCreated <= '2011-11-09 23:59:59')
.Where(y => y.Table2.Table3.Any(u => u.Id == 1))
.Take(10);
One of the things I like most about Linq is that it will combine queries together, so I break a complicated query into subqueries and let Linq recombine them all.
Using that basis, does something like this work.
DateTime startDate = new DateTime(2011,11,9);
DateTime endDate = new DateTime(2011,11,9,23,59,59);
var table3Ids = (from r in Pos.dbo.Table3 where id = 1 select r.id) ;
var query1 =
(
from t1 in Pos.dbo.Table1
where t1.Table2.Id == 1 && t1.Date >= startDate && t1.Date <= endDate
where table3Ids.Contains(t1.Table2.Id)
group t1 by new { t1.Table2.Id , t1.Table2.Name} into results
select new
{
results.Key.Id ,
results.Key.Name ,
Total = results.Sum(r=> (r.Column1 + r.Column2 + r.Column3))
}
);
var query2 = (from r in query1 orderby r.Total descending select r).Take(10);
var query3 = (from r in query2 orderby r.Name select r);
var list = query3.ToList();
Here's my shot - it's a bit hard without knowing the actual data structure or the expected results:
var query = db.Table1
.Join(db.Table2, table1 => table1.Id, table2 => table2.Id, (t1, t2) => new {
Id = t2.Id,
Name = t2.Name,
Total = (t1.Column1 + t1.Column2 + t1.Column3),
Date = t1.Date //you didn't use a table alias for this field, so I'm not sure which table it comes from
})
.Where(x => x.Date >= new DateTime(2011, 11, 9)
&& x.DateCreated <= new DateTime(2011, 11, 9, 23, 59, 59))
.Join(db.Table3, x => x.Id, table3 => table3.Id, (x, t3) => new {
Id = x.Id,
Name = x.Name,
x.Total
})
.Where(x => x.Id == 1)
.OrderByDescending(x => x.Total)
.ThenBy(x => x.Name)
.Take(10)
.ToList()
Because that might be the craziest Linq statement I've ever written, don't assume it'll work the first time, but it's at least a good starting point.

Use LINQ to group data from DataTable

I want to use LINQ to group data from a DataTable (columns: userid, chargetag, charge).
The content could look like this:
userid chargetag charge
-----------------------------
user1 tag3 100
user2 tag3 100
user3 tag5 250
I need something like this as a result:
chargetag count sum
-------------------------
tag3 2 200
tag5 1 250
This is what I have so far:
var groupedData = from b in dataTable.AsEnumerable()
group b by b.Field<string>("chargetag") into g
let count = g.Count()
select new
{
ChargeTag = g.Key,
Count = count,
};
I can extract the name of the chargetag and the number of it.
How would I have to change the LINQ query to access the sum of charges as well?
Thanks in advance :-)
Regards,
Kevin
That's pretty easy - just use the Sum extension method on the group.
var groupedData = from b in dataTable.AsEnumerable()
group b by b.Field<string>("chargetag") into g
select new
{
ChargeTag = g.Key,
Count = g.Count(),
ChargeSum = g.Sum(x => x.Field<int>("charge"))
};
(I've removed the let clause here as it wasn't really buying you anything.)
Now that may be inefficient; it may end up grouping twice in order to perform two aggregation operations. You could fix that like with a query continuation like this, if you really wanted:
var groupedData = from b in dataTable.AsEnumerable()
group b by b.Field<string>("chargetag") into g
select new
{
ChargeTag = g.Key,
List = g.ToList(),
} into g
select new
{
g.ChargeTag,
Count = g.List.Count,
ChargeSum = g.List.Sum(x => x.Field<int>("charge"))
};
Or with a let clause instead:
var groupedData = from b in dataTable.AsEnumerable()
group b by b.Field<string>("chargetag") into g
let list = g.ToList()
select new
{
ChargeTag = g.Key,
Count = list.Count,
ChargeSum = list.Sum(x => x.Field<int>("charge"))
};

Categories