how to avoid two columns contain 0 in linq - c#

assume as i have to shown the list of value in the screen
iam taking the list using linq
Student English Hindi Tamil MArathi
------- --------- ------- ------- ---------
Deepan 56 65 34 45
Mohan 45 34 0 23
Murali 56 89 0 0
Assume that i have these values in db.....
I dont want to show if (tamil and marathi ) is 0.....if both r contains 0 means ....
i have to avoid that row while taking from database using linq ...eg(murali)...but i dont want to avoid Mohan.....pls give me the linq query
Now i tried this
var ulist = (from c in CustomerTransactions
where c.TransTypeID==12
select new
{
Student=c.Student,
English=c.English,
Hindi=c.Hindi,
Tamil=c.Tamil,
Marathi=c.Marathi
}).ToList().OrderBy(b => b.Student).Where(x => x.Marathi!=0 );

You can combine several conditons in a single where-statement:
.Where(x => x.Marathi !=0 && x.Tamil != 0)
This will select only those entries where both conditions pass (meaning both Marathi and Tamil are not 0).

This is what you can use if Lambda is fine for you. You can combine all the 3 checks in first Where clause itself, instead of specifying the conditions at 2 different places.
CustomerTransactions.Where(c => c.TransTypeID==12 && !(c.Marathi == 0 && c.Tamil == 0))
.OrderBy(c => c.Student)
.Select(c => new {
Student=c.Student,
English=c.English,
Hindi=c.Hindi,
Tamil=c.Tamil,
Marathi=c.Marathi
}).ToList();

Related

LINQ: analog for sql's EXISTS?

Let's say I have a few people in a collection "Employees":
Name | Position | Age
------+----------+----
Tom | Manager | 35
Hank | Driver | 38
Harry | Driver | 45
... | ... | ...
Mark | Driver | 30
----------------------
and I want to get all Drivers if there is at least one among them who's older that 40 years old.
Could you help me to complete my LINQ?
UPD. I'd like to do this task using a single LINQ and perfomance has no matter. So decision
var allDrivers = Employees.Where(n => n.Position == "Driver").ToList();
return allDrivers.Any(n => n.Age > 40)
? allDrivers
: new List<Employee>();
is good, but I can't mark it as an answer.
In this particular case I need to get Hank, Harry and Mark. Because all they're drivers and Harry is 45 (>40). But if Harry was 39 I would get nothing as a result because in this case all drivers were under 40.
So if I were to parse "I want to get all Drivers if there is at least one among them who's older that 40 years old" literally, it'd be
var allDrivers = Employees.Where(n => n.Position == "Driver").ToList();
return allDrivers.Any(n => n.Age > 40)
? allDrivers
: new List<Employee>();
Or something similar.
For one-query functional craziness:
(int maxAge, List<Employee> result) = Employees
.Aggregate(
(age: 0, list: new List<Employee>()),
(al, n) => n.Position == "Driver"
? (Math.Max(al.age, n.Age), al.list.Concat(new [] {n}).ToList()
: al));
return maxAge > 40 ? result : new List<Employee>();
This is just PoC that you CAN. But remember - when asking yourself if you could, don't forget to ask yourself if you should :)
If you really want it inside one statement (this feels very artificial to me) then you can do this:
IEnumerable<Employee> result =
employees.GroupBy(n => n.Position)
.Where(g => g.Key == "Driver" && g.Max(x => x.Age) > 40)
.FirstOrDefault();
Don't forget to do
return result ?? Enumerable.Empty<Employee>();
if you want to return an empty result instead of null when nothing is found.

Linq Group by to column [duplicate]

This question already has answers here:
Is it possible to Pivot data using LINQ?
(7 answers)
Closed 5 years ago.
I have a list of items with a property code and I want to group by eventId and create a table representation where code values are transformed to columns.
Every triple (event, code,amount) is unique.
I want to transform this
eventId code amount
1 A 100
1 B 101
1 C 102
2 A 103
2 C 104
3 B 105
....
to this
eventId A B C
1 100 101 102
2 103 0 104
3 0 105 0
...
var table=from x in list
group x by x.eventId into gr
select new
{
eventId=gr.Key,
....
}
You need to filter on grouped result and project in to anonymous object :
var table=from x in list
group x by x.eventId into gr
select new
{
eventId=gr.Key,
A = gr.Where(x=>x.code == "A").Sum(x=>x.amount),
B = gr.Where(x=>x.code == "B").Sum(x=>x.amount),
C = gr.Where(x=>x.code == "C").Sum(x=>x.amount)
}
It's actually quite neat to use a lookup:
var table =
from x in list
group x by x.eventId into gr
let lookup = gr.ToLookup(y => y.code, y => y.amount)
select new
{
eventId = gr.Key,
A = lookup["A"].Sum(),
B = lookup["B"].Sum(),
C = lookup["C"].Sum(),
};
I get this result:

How to use Distinct for this select query in LINQ [duplicate]

This question already has answers here:
LINQ: Distinct values
(8 answers)
Closed 8 years ago.
I have following query:
var query = from product in SH_Products
from product_group in SH_ProductGroups_Products.Where(c=>c.ProductID == product.ID)
from manufacturer in SH_Manufacturers.Where(c=>c.ID == product.ManufactureID)
from attributeOption_product in SH_AttributeOptions_Products.Where(c=>c.ProductID == product.ID).DefaultIfEmpty()
where !product.IsDeleted
&& !product_group.IsDeleted
&& !manufacturer.IsDeleted
&& product.Status != 0
select new
{
product.ID,
ProductGroupID = product_group.ProductGroupID,
AttributeOptionID = (int?)attributeOption_product.AttributeOptionsID,
product.ManufacturerID
};
query.Distinct().Dump();
Below is the sample output:
ID ProductGroupID AttributeOptionID ManufacturerID
1 1 75 1
1 1 76 1
2 3 17 2
3 2 3 1
4 1 NULL 1
As you see, we have 2 record with ID = 1, and I don't wanna this, how I can remove this one?
I wrote this query for filtering section of my project.
I have filtering by ProductGroupID, AttributeOptionID, ManufacturerID, all of them are multi-select-able !
thanks !
As I said in the comments, you can use the other overload of Distinct extension method which asks for an EqualityComparer.
Or another way you can use
query.GroupBy(item => item.ID).Select(grp => grp.First())...
instead of
query.Distinct()...
Please do not forget that the output will not contain the second record in your sample output.
If the key of your records is not only ID but ID and ProductGroupID instead, usage can be
query.GroupBy(item => new {item.ID, item.ProductGroupId} ).Select(grp => grp.First())...

Sort column in DataTable with same values

I have a question about sorting in Datatable. I have a table like below and want to sort it from small to big. The problem is when i have same numbers, i want to have the first as the last and so on...
Table:-----------------------------------After Sorting:
Name Bit Size Name Bit Size (corrected)
A 0 1 A 0 1
C 1 2 C 1 2
B 1 3 B 1 3
D 1 1 D 1 1
Result that i want:
Name Bit Size (corrected)
A 0 1
D 1 1
B 1 3
C 1 2
My Code:
arraySBit.DefaultView.Sort = "Bit";
arraySBit = arraySBit.DefaultView.ToTable();
You can use Linq-To-DataTable:
var tblSorted = table.AsEnumerable()
.OrderBy(r => r.Field<int>("Bit"))
.CopyToDataTable();
Edit: But actually DataView.Sort should also work (tested).
Since you have edited your question. Your requirement seems weired. If the Bit is the same you don't want to order by something but you want to reverse the "order" of the rows of the equal rows (so the Ordinal position in the DataTable).
This does what you want although i'm not sure that it's really what you need:
DataTable tblSorted = table.AsEnumerable()
.Select((Row, Ordinal) => new {Row,Ordinal})
.OrderBy(x => x.Row.Field<int>("Bit"))
.ThenByDescending(x => x.Ordinal)
.Select(x => x.Row)
.CopyToDataTable();
Basically it passes the index of the row in the table via this overload Enumerable.Select into an anonymous type. Then it'll sort by Bit first and the index/ordinal second.
A workaround,
After these lines, you should have result in arrySBit as you want
DataTable arrySBitClone = arrySBit.Copy();
arrySBit.DefaultViewSort.Sort = "Bit";
bool different = false;
for(int i=0; i<arrySBit.Rows.Count; i++)
{
if(arrySBit.Rows[i]["Bit"]!=arrySBitClone.Rows[i]["Bit"])
{
difference = true;
break;
}
}
if(!different)
{
arrySBit = arrySBit.Copy();
}
if i'm getting right your question.
why not use Select?
DataTable dt = arraySBit.Select("", "Bit, Size").CopyToDataTable();
The first parameter of the Select Method is a condition to filter, the second is an Order By, so it should work

Linq-to-entities: Easy to find max value in SQL, but difficult in LINQ?

I've started using Linq-to-entities with .NET 3.5, and I've come across a scenario that I can do real easy in SQL, but I'm having great difficulty with linq.
I have a table in a SQL database with three fields, for purposes of this example I'll call them foo, bar, and foo_index and populate them like so:
Blockquote
foo | bar | foo_index
555 101 1
555 101 2
555 101 3
555 101 4
555 101 5
To get what bar is at the max foo_index where foo=555 the SQL is
SELECT bar, max(foo_index) as max_foo_index
FROM T
WHERE foo=555
GROUP BY bar
I've written some linq-to-entities code in C# that works, but I have a feeling there is a much more elegent solution out there, and that I'm missing some concept that would make the following much easier. Also, is there any way other then a foreach to get the data out of a var?
db_entity db = new db_entity();
var q =
from table in db.T
where table.FOO == 555
select new { table.BAR, table.FOO_INDEX };
var q2 =
from t2 in q
where t2.FOO_INDEX == table.Max(r => r.FOO_INDEX)
select new { t2.BAR };
int result = 0;
foreach (var record in q2}
{
result = record.BAR.Value;
}
Any help or guidance would be appreciated, Thanks!
I think this should work:
var query = from item in db.T
where item.FOO == 555
group item by item.BAR into g
select new { Bar = g.Key, Max = g.Max(x => x.FOO_INDEX) };
So basically you're taking the same approach as in the SQL: group the data, then take the key for the group and the maximum FOO_INDEX within the group.
You can group elements in LINQ to Entities the same way you do in SQL. The syntax would look something like:
var q = from t in db.T
where t.FOO == 555
group t by t.BAR into g
select new {
Bar = group.Key,
Max = g.Max(b => b.FOO_INDEX)
};

Categories