C# query with count - c#

I have a list of users having several properties and I want to know who and how had the same code (which is an user property)
For example :
user 1: Jacob, code 1
user 2: Charlie, code 1
user 3: Thomas, code 2
I need to query and have a result like this :
+--------+--------+
| Object | Count |
+--------+--------+
| user 1 | 2 |
| user 2 | 2 |
| user 3 | 1 |
+--------+--------+
"2" because 2 users have the same code and "1" because just one had the code
Can someone help me for this please?

You can get using this linq. change tablename and field name according to yours.
(from user in _context.Users
let count = _context.Users.Where(p=>p.code == user.code).Count()
select new {user.username, count = count}).ToList()

Let's try below code. I think it can help you well:
var result = mycontext.users.GroupBy(p=>p.User).Select(p=>new { Object = p.Key, Count = p.Count()});

Related

Insert values in col1 of list 1 from col 2 of list 2 based on a common column

List 1:
| User Id | Latest |
+---------------------+------------------+
| 1 | 1 |
| 2 | 3 |
| 3 | 3 |
| 4 | 0 |
List 2:
| User Id | Latest | Rating |
+---------------------+------------------+------------------+
| 1 | null | 10 |
| 2 | null | 12 |
| 3 | null | 11 |
| 4 | null | 16 |
I want to insert the values of the Latest column of List1 into the Latest column of List2 based on joining/comparing values of the User Id column in both lists.
I can use a foreach loop but that would run n*m I guess and look ugly. Is there a way to do it with LINQ or efficiently?
Regards.
Junaid
var result = from i1 in List1
join i2 in List2
on i1.UserId equals i2.UserId
select new
{
i2.UserId,
i1.Latest,
i2.Rating
};
you can do it with LINQ :
Try this code :
List2.ForEach(item1 =>
{
item1.Latest = List1.FirstOrDefault(item2 => item2.UserId == item1.UserId)?.Latest;
});
Note That, Latest must be Nullable.
LINQ will never change any of the source sequences, it can only extract data from it.
You will have to enumerate over the extracted data to update your original tables.
var recordsToUpdate = List2.Join(List1, // join List2 and List1
list2Row => list2Row.UserId, // from every row in List2 take UserId
list1Row => list1Row.UserId, // from every row in List1 take UserId
(list2Row, list1Row) => new // when they match make one new object
{
Id = list2Row.UserId, // take UserId from list2
Latest = list1Row.Latest, // take Latest from list1
Rating = list2Row.Rating, // take Rating from list2
})
.ToList(); // execute the query
I don't know how you update your records. Entity framework? SQL? it will be something like this:
foreach (var recordToUpdate in recordsToUpdate)
{
UpdateRecord(recordToUpdate.UserId, recordToUpdate.Latest, recordToUpdate.Rating)
// TODO: implement this function
}
Try something like this. this may fix your issue with adding the Latest value from List1 to List2.
List2.AddRange(List1.Select(user => new List1{
Latest = user.Latest,
UserID = user.UserID
}));

LINQ join tables with value if no match

I know that there are some examples but I could not apply them on my code. I am pretty new to Linq and SQL. I have two tables I want to join.
First Table:
--------------
| Id | Count |
--------------
| 1 | 10 |
--------------
| 2 | 4 |
--------------
Second Table:
--------------
| Id | Name |
--------------
| 1 | Tom |
--------------
| 2 | John |
--------------
| 3 | Nick |
--------------
| 4 | Max |
--------------
As you can see, the second table has more records than the first. My goal is to join them based on the Id. The problem is that after I have joined the tables it only displays the matching records, which is Id 1 and 2. Though I want to display every Id (from 1 to 4) and if there is no match in both tables, there should be a default value 0.
It should look like this:
----------------------
| Id | Name | Count |
----------------------
| 1 | Tom | 10 |
----------------------
| 2 | John | 4 |
----------------------
| 3 | Nick | 0 |
----------------------
| 4 | Max | 0 |
----------------------
So far I have got this code:
// first table
var listCount = entity.tblKundes.Where(x => x.Studio == 2)
.Select(x => new { x.Id, x.Name})
.GroupBy(x => x.Name).ToList();
// second table
var listBerater = entity.tblUsers.Where(x => x.Studio == 2)
.Select(x => new { x.Id, x.Name})
.ToList();
// This join should be edited so that it displays non matching records as well
var test = listCount.Join(
listBerater,
count => count.Key,
berater => berater.Id,
(count, berater) => new { listCount = count, listBerater = berater }
).ToList();
Edit:
var test2 = (from list in listCount
join berater in listBerater on list.Berater equals berater.Id into gj
from sublist in gj.DefaultIfEmpty()
select new { sublist.Id, sublist.Nachname, sublist.Vorname }).ToList();
There is a typical concept in every Structured Query Languages which is called "Left join". Left-Join means that you will have all rows of data from first table even there is no equivalent in the second one. "Inner-Join" is a little different and only looks for matched rows of data.
Here you can find enough and complete information about your issue.
Left Join

How to Join with a column having Comma Separated Values in Linq

I have one master table Category.
ID | Name
----------
1 | Category1
2 | Category2
3 | Category3
4 | Category4
And Another Table Details have field like
ID | CategoryId | Detail
--------------------
1 | 1,2,3 | Test1
2 | 3,4 | Test2
Here the Category Id stored as comma separated values.
Now i want the result as
ID | CategoryName
----------------
1 | Category1,Category2,Category3
2 | Category3,Category4
AnyOne Have idea ..??
You can use link this:
private static void commaSeperate(List<classname> obj)
{
string delimeter = ",";
Console.WriteLine(obj.Aggregate((i, j) => new classname { Name = (i.Name + delimeter + j.Name) }).Name);
Console.ReadKey();
}
This is just a sample, please modify according to your conditions.
Hope this will help you.
This could be the solution if our retrieve the data into memory first.
var q = from d in Details
from m in Master
select new {Id = d.Id, CategoryName = String.Join(m.Where(i=> d.CategoryId.Split(',').Cast<int32>().Contains(i.Id).Select(i => i.Name).ToArray(), ',')}
You can't join these two tables but I think below query would work for your result:
(from de in datacontextobj.Details
from ca in datacontextobj.Category
where de.CategoryId.Contains(ca.ID)
select de.ID, ca.Name).ToList();

Inputing Value in sql after counting c#

I'm kind of new to this but I'll try to give as much detail as possible. This is my SQL table.
Customers
Customers_Id (PK) | First | Last | Address | Phone | Tech_Id (FK) |
-------------------+-------+-------+--------------+----------+--------------+
1 | Bob | Smith | 123 Fake St. | 3298492 | 1 |
2 | John | Man | 123 Noe St. | 2930482 | 1 |
3 | Tom | Lee | 123 Polk St. | 9308523 | 2 |
...
Tech
Tech_Id (PK) | First | Last | Phone | Customer_Count |
--------------+-------+-------+---------+----------------+
1 | Tim | Bo | 9384027 | |
2 | Andy | Wong | 9374927 | |
3 | Jack | Help | 2183847 | |
...
I'm trying to find the best way to count how many customer that each tech has either using SQL Query or C# coding. I was thinking of doing query with Count and then insert into the Customer_Count in Tech table.
I'm using visual studio 2012 and SQL is created locally in visual studio. Please help!
You can do it through SQL - using a GROUP BY clause to group the result by each tech. You can use the COUNT function to return the number of customers assigned to each tech. You can put this in an UPDATE statement to update the customer_count field in the tech table for each tech.
For example:
UPDATE t
SET t.customer_count = COUNT(c.customer_id)
FROM tech t
INNER JOIN customers c ON c.tech_id = t.tech_id
GROUP BY c.tech_id
Remove the Customer_Count column from the tech table. It's best not to make columns which duplicate available data unless there's a valid performance reason. If you want it displayed as such, then create a view:
SELECT t.tech_id,
t.first,
t.last,
t.phone,
(SELECT COUNT(c.customer_id)
FROM customers c
WHERE c.tech_id = t.tech_id) AS Customer_Count
FROM tech t
Now you can query it like a table, but you're not tasked with maintaining data which is always up to date through this view.
I prefre to using Sql ,but failed...Disappionted..
But I am sure that you can use Ado.net to do this job.
Here is C# demo code.
//query from db use C#
var allCus = new List<Customers>();
var gps = allCus.GroupBy(w => w.Tech_Id);
foreach(var gp in gps) {
var techId = gp.Key;
var cnt = gp.Count();
//update Tech set Customer_Count = cnt where Tech_Id = techId
}
Here is Sql version
update Tech set Customer_Count = (select IdAndCnt.cnt from (select Tech_Id,count (Tech_id) as cnt from Customers group by Tech_Id ) as IdAndCnt where Tech.Tech_Id = IdAndCnt.Tech_Id)
Holp it works.

List of unique strings in database table using Linq?

I have a "Tickets" table with somewhat following structure (removed unnecessary columns)
int | string | int |
ID | Window | Count |
------------------------
0 | Internet | 10 |
1 | Phone | 20 |
2 | Fax | 15 |
3 | Fax | 10 |
4 | Internet | 5 |
. | . | . |
. | . | . |
And I have mapped this table to a class "Ticket". So I can get all records like this:
var tickets = from t in db.Tickets
select t;
Now I need to get the list of unique window names in the table. For above table, list would look something like:
Internet
Phone
Fax
Is there anyway to create this list without fetching all records and iterating over them?
I am using SQL Server 2008 express edition.
EDIT:
Thanks for the answers guys it solved the above problem. Just being greedy but is there any way to also get the total of count for each window. For example:
Internet = 15
Phone = 25
Fax = 20
How about:
var tickets = db.Tickets.Select(t => t.Window).Distinct();
I prefer to only use query expressions when I'm doing more than one operation, but if you like them the equivalent is:
var tickets = (from t in db.Tickets
select t.Window).Distinct();
To get the counts, you need to group:
var tickets = from t in db.Tickets
group t by t.Window into grouped
select new { Window=grouped.Key,
Total=grouped.Sum(x => x.Count) };
foreach (var entry in tickets)
{
Console.WriteLine("{0}: {1}", entry.Window, entry.Total);
}
Note that this should all end up being performed at the database side - examine the SQL query to check this.
var query2 = from ticket in db.tickets
group window by ticket.Window into result
select new
{
Name = result.Window,
Sum = result.Sum(i => i.Count)
};
The query will be evaluated inside the store.
var windows = db.Tickets.Select(ticket => ticket.Window).Distinct();
Linq Samples Part 11 by Bill Wagner should help you. Just call the Distinct() function on your Linq result. It's as simple as that.
var tickets = (from t in db.Tickets
select t).Distinct();
[EDIT]
Concering the numbers of the occurences, see this example as a hint.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 5 };
var numberGroups =
from n in numbers
group n by 5 into g
select g;
g.Count(); // occurences
You can use the .Distinct() operator - it'll make a SELECT DISTINCT to the database, giving exactly what you ask for.

Categories