Linq - join two tables and count - c#

Have two tables:
Catalog
|----------|----------|-----------|
| Id | Name | CreatedBy |
|----------|----------|-----------|
| 1 | Catalog1 | 1 |
| 2 | Catalog2 | 1 |
| 3 | Catalog3 | 1 |
| 4 | Catalog4 | 2 |
|----------|----------|-----------|
TemplateOnCatalog
|------------|-----------|
| TemplateId | CatalogId |
|------------|-----------|
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 4 |
|------------|-----------|
Using c# and Linq, how to get a list of all the catalogs, where CreatedBy = 1, and count the number of templates in the catalog. If no templates, the count value should be 0 (or empty).
Expected result:
|------------|-------------|-------------------|
| CatalogId | CatalogName | NumberOfTemplates |
|------------|-------------|-------------------|
| 1 | Catalog1 | 2 |
| 2 | Catalog2 | 3 |
| 3 | Catalog3 | 0 |
|------------|-------------|-------------------|
I try the following, but it doesn't take catalogs without templates:
var templateCatalogs =
from templateCatalog in db.Catalog.AsNoTracking()
join totc in db.TemplateOnCatalog
on templateCatalog.Id equals totc.CatalogId
where
templateCatalog.CreatedBy == 1
orderby templateCatalog.Name
group new { templateCatalog, totc }
by new { templateCatalog.Name, templateCatalog.Id } into result
select new
{
CatalogId = result.Key.Id,
CatalogName = result.Key.Name,
NumberOfTemplates = result.Count()
};

Related

Print value based on multiple column

my table
+----+----------+---------+---------+----------+
| ID | State A | State B | State C | Duration |
+----+----------+---------+---------+----------+
| 1 | a | a | a | 12 |
+----+----------+---------+---------+----------+
| 2 | a | a | a | 15 |
+----+----------+---------+---------+----------+
| 3 | a | a | b | 12 |
+----+----------+---------+---------+----------+
| 4 | a | b | b | 30 |
+----+----------+---------+---------+----------+
| 5 | b | b | b | 12 |
+----+----------+---------+---------+----------+
IF THE 3 COLUMNS AS THE SAME VALUE AND DURATION <15
result as the following :
+----+-----------------+
| ID | THE RESULT |
+----+-----------------+
| 1 | a is the winner |
+----+-----------------+
This is a filter along with concat():
select concat(statea, ' is the winner')
from t
where statea = stateb and stateb = statec and duration < 15

how to assign colour to duplicate values in a list

how to assign colour to duplicate values in a list
This my table
| user_id | account_no | zip | date |
| 1 | 123 | 55555 | 12-DEC-09 |
| 1 | 123 | 66666 | 12-DEC-09 |
| 1 | 123 | 55555 | 13-DEC-09 |
| 2 | 456 | 77777 | 14-DEC-09 |
| 2 | 456 | 77777 | 14-DEC-09 |
| 2 | 789 | 77777 | 14-DEC-09 |
| 2 | 789 | 77777 | 14-DEC-09 |
You can assign a color in this way:
var userIdGroups = db.TableName.GroupBy(x => x.user_id).AsEnumerable();
var itemsWithColors = userIdGroups
.SelectMany(g => g.Select((x, index) => index == 0
? new { Item = x, Color = Color.Black }
: new { Item = x, Color = Color.Red }));
Now use a foreach loop to process this query and add these items to your UI control.

EF Code First Configuration Duplicating Records

So I'm attempting to populate a table with seed data in EF5. I have an Enum of all 50 states and DC. I also have a lookup table of RequestTypes with IDs 1-6. It would be something like this:
+----+----------+-------------+------------+
| Id | State | SurveyId | RequestType|
+----+----------+-------------+------------+
| 1 | Alabama | 0 | 1 |
| 2 | Alabama | 0 | 2 |
| 3 | Alabama | 0 | 3 |
| 4 | Alabama | 0 | 4 |
| 5 | Alabama | 0 | 5 |
| 6 | Alabama | 0 | 6 |
+----+----------+-------------+------------+
The model that represents this table:
public class StateSurveyAssignment{
public long Id { get; set; }
public string State { get; set; }
public long RequestTypeId { get; set; }
public long SurveyId { get; set; }
}
And the code to seed the database in the Configuration.cs:
foreach (var state in Enum.GetValues(typeof(State))) {
foreach (var type in context.RequestTypes){
context.StateSurveyAssignments.AddOrUpdate(
ssa => ssa.Id,
new StateSurveyAssignment{
State = state.ToString(),
RequestTypeId = type.Id
}
);
}
}
My problem is that instead of updating/doing nothing to unchanged records, the seed method is duplicating each row. I've attempted to manually set the Id but had no luck.
EDIT:
This is what the database duplication looks like:
+----+----------+-------------+------------+
| Id | State | SurveyId | RequestType|
+----+----------+-------------+------------+
| 1 | Alabama | 0 | 1 |
| 2 | Alabama | 0 | 2 |
| 3 | Alabama | 0 | 3 |
| 4 | Alabama | 0 | 4 |
| 5 | Alabama | 0 | 5 |
| 6 | Alabama | 0 | 6 |
| ...| ... | ... | ... |
|307 | Alabama | 0 | 1 |
|308 | Alabama | 0 | 2 |
|309 | Alabama | 0 | 3 |
|310 | Alabama | 0 | 4 |
|311 | Alabama | 0 | 5 |
|312 | Alabama | 0 | 6 |
+----+----------+-------------+------------+
My Solution
I swear I'd tried setting my own Id at some point but tried it again per the answer and it seems to have worked. My final solution:
int counter = 1;
foreach (var state in Enum.GetValues(typeof(State))) {
foreach (var type in context.RequestTypes){
context.StateSurveyAssignments.AddOrUpdate(
ssa => ssa.Id,
new StateSurveyAssignment{
Id = counter,
State = state.ToString(),
RequestTypeId = type.Id
}
);
counter++;
}
}
The problem could be that the Id property in your StateSurveyAssignment class is an Identity column in the database.
This means that each row is not unique.
For example you try to insert the following several times using AddOrUpdate()
var model = new StateSurveyAssignment
{
State = "Alabama",
RequestTypeId = 1L,
SurveyId = 0L
};
Then each entry would have a different Id and thus you'll have duplicates.

Data grouping in SQL

I am working on a small project using C# and EF5.0 and I need to group some data. Let say I have table of columns in a building like shown below.
+----------+--------Columns Table--+------+------+
| ColumnID |ColumnName|Width|Length|Height|number|
+----------+----------+-----+------+------+------+
| 1 | C101 | 50 | 70 | 250 | 1 |
| 2 | C102 | 70 | 70 | 250 | 1 |
| 3 | C103 | 70 | 60 | 250 | 1 |
| 4 | C104 | 90 | 70 | 250 | 1 |
| 5 | C105 | 40 | 50 | 250 | 1 |
| 6 | C106 | 50 | 70 | 250 | 1 |
| 7 | C107 | 50 | 60 | 250 | 1 |
| 8 | C108 | 70 | 70 | 250 | 1 |
+----------+----------+-----+------+------+------+
I need a C# code to see the above data groupped like this:
+----------+---Groupped Columns Table-----+------+
|G_ColumnID|ColumnName|Width|Length|Height|number|
+----------+----------+-----+------+------+------+
| 1 |C(101-106)| 50 | 70 | 250 | 2 |
| 2 |C(102-108)| 70 | 70 | 250 | 2 |
| 3 | C103 | 70 | 60 | 250 | 1 |
| 4 | C104 | 90 | 70 | 250 | 1 |
| 5 | C105 | 40 | 50 | 250 | 1 |
| 6 | C107 | 50 | 60 | 250 | 1 |
+----------+----------+-----+------+------+------+
I prefer clues than the exact solution.
EDIT : Below code shows my current state. I think I can find the columns with the same Height, Width and Length using this code. But I am not sure how to generate a new name for the group.
using (pehlivanEntities context = new pehlivanEntities())
{
foreach (var item in context.table1)
{
int id = item.ColumnID;
foreach (var item2 in context.table1)
{
int id2 = item2.ColumnID;
if (id != id2)
{
if (item.Width == item2.Width)
{
if (item.Length == item2.Length)
{
if (item.Height == item2.Height)
{
//Alter item.ColumnName
//increase item.number by one
//Remove item2
}
}
}
}
}
}
}
Well you'd start with grouping on a composite key:
var groups = myData.GroupBy(d => new{d.Width, d.Length, d.Height})
then
groups
.Select(g => new {
g.Key.Width,
g.Key.Length,
g.Key.Height,
columnNames = g.Select(x => x.ColumnName),
number = g.Count()})
then a bit of string manipulation on the columnNames field

DataGridView Matching

I have 2 DataGridViews (DGVs).
theChipDGV will contain data like this (except with many more columns):
______________________________________________________________
| NAME | P/N | X | Y | ROTATION | PACKAGE |
|________|________|________|________|____________|___________|
| R16 | 147479 | 20.325 | 100.000| 0 | 0603 |
| C6 | 14739 | -5.325 | -10.105| 180 | 0603 |
| U45 | 123456 | 12.345 | 12.345 | 45 | 0402 |
|________|________|________|________|____________|___________|
theDataBaseDGV will contain data like this (except with many more columns):
____________________________________________________________________________________________
| PACKAGE | DESCRIPTION | FEEDER | VISION | SPEED | MACHINE | WIDTH | TIME |
|___________|_______________|__________|__________|_________|___________|_________|_______ |
| PLCC20 | N/A | 25MM | N/A | 3 | UNIVERSAL | 12MM | 0.05 |
| 0603 | 0603C_1.0 | 8X4 | 1 | 1 | FUJI-1 | 8MM | 20 |
| 0603 | 0603R_1.0 | 12X4 | 1 | 5 | FUJI-2 | 16MM | 0.20 |
|___________|_______________|__________|__________|_________|___________|_________|_______ |
What I would like to do is match the column in theChipDGV labeled PACKAGE with the same labeled column in theDataBaseDGV. If there is a match, the entire row will be concatted into a new DGV (let's label it: theFinalDGV). Also, if the PACKAGE type is matched and is also in the next line (like 0603) it will check to see if the column labeled Name in theChipDGV starts with a R or a C. Depending on which it starts with will determine the rest of the columns from theDataBaseDGV that will be used.
SO:
theFinalDGV will look like this:
_____________________________________________________________________________________________________________________________________________
| NAME | P/N | X | Y | ROTATION | PACKAGE | DESCRIPTION | FEEDER | VISION | SPEED | MACHINE | WIDTH | TIME |
|________|________|________|________|____________|___________|_______________|__________|__________|_________|___________|_________|________|
| R16 | 147479 | 20.325 | 100.000| 0 | 0603 | 0603R_1.0 | 12X4 | 1 | 5 | FUJI-2 | 16MM | 0.20 |
| C6 | 14739 | -5.325 | -10.105| 180 | 0603 | 0603C_1.0 | 8X4 | 1 | 1 | FUJI-1 | 8MM | 20 |
| U45 | 123456 | 12.345 | 12.345 | 45 | 0402 | | | | | | | |
|________|________|________|________|____________|___________|_______________|__________|__________|_________|___________|_________|________|
Notice, if there is no match it leaves the columns empty.
So:
Does anyone know how I can possibly go about doing this? I mostly would like to know how to match the values from 1 column with another and if there are multiple columns from theDataBaseDGV that have the same values.. then how to properly match those.
int chipRowCount = theChipDGV.RowCount;
int dataBaseRowCount = theDataBaseDGV.RowCount;
for (int count = 0; count < chipRowCount; count++)
{
for (int i = 0; i < dataBaseRowCount; i++)
{
if (theChipList[count].PkgStyle.Equals(theDataBaseList[i].PackageType) || (theChipList[count].PkgStyle.Contains(theDataBaseList[i].PackageType) &&
theDataBaseList[i].PartDescription.Contains("R") && theChipList[count].Name.StartsWith("R")) || ((theChipList[count].PkgStyle.Contains(theDataBaseList[i].PackageType) &&
theDataBaseList[i].PartDescription.Contains("C") && theChipList[count].Name.StartsWith("C"))))
{
if (!theChipList[count].Used)
{
theChipList[count].Used = true;
theFinalList.Add(new LoadLine(theChipList[count].Name, theChipList[count].PartNumber,
theChipList[count].XPlacement, theChipList[count].YPlacement, theChipList[count].Rotation,
theChipList[count].PkgStyle, theDataBaseList[i].PackageType, theDataBaseList[i].PartDescription,
theDataBaseList[i].Feeder, theDataBaseList[i].Vision, theDataBaseList[i].Speed,
theDataBaseList[i].Machine, theDataBaseList[i].TapeWidth, 0));
theFinalDGV.DataSource = theFinalList;
}
}
}
}
for (int count = 0; count < theChipList.Count; count++)
{
if (!theChipList[count].Used)
{
theFinalList.Add(new LoadLine(theChipList[count].Name, theChipList[count].PartNumber,
theChipList[count].XPlacement, theChipList[count].YPlacement, theChipList[count].Rotation,
theChipList[count].PkgStyle, string.Empty, string.Empty, string.Empty, string.Empty,
string.Empty, string.Empty, string.Empty, 0));
}
}

Categories

Resources