Select distinct column names in Linq - c#

My table contains several columns and I need to select distinct rows in two specific columns using Linq.
My SQL equivalent is:
Select distinct Level1Id, Level1Name
from levels
What I currently do is:
db.levels.GroupBy(c=> c.Level1Id).Select(s => s.First())
This will retrieve the whole row not only Level1Id and Level1Name. How can I specify the columns I want to retrieve in this linq query?

With Select, you can specify the columns in an anonymous object and then use Distinct on that:
db.levels.Select(l => new{ l.Level1Id, l.Level1Name }).Distinct();

try
db.levels.Select(c => new {c.Level1Id, c.Level1Name}).Distinct();

Specify the two columns in your LINQ query select, create an anonymous object with Level1Id and Level1Name properties:
var query = (from v in db.levels
select new { Level1Id = v.Level1Id, Level1Name = v.Level1Name }).Distinct();
and use each item like this:
foreach (var r in query){
int valId = r.LevelId;
int level = r.Level1Name;
//do something
}

You are so close, one more step:
var result = db.levels.GroupBy(c=> new { c.Level1Id, c.Level1Name })
.Select(s => s.First())
The key thing is: Anonymous type uses structural comparison, that's why GroupBy or any other answer do work.

Related

Filter element from SQL Database table using LINQ

I'm trying to learn LINQ. I have
var mydata = from k in db.emp_mains select k.empname.Equals("me");
But after this statement i the auto complete wont complete the table fields name
foreach(var x in mydata)
{
---> Autocomplete not working Console.WriteLine(x.empname);
}
Why is this happening? Kindly advice.
Your condition need to go into where clause
var mydata = (from k in db.emp_mains
where k.empname.Equals("me")
select k
).ToList();
What you want is to filter with the where statement:
var myData = from k in db.emp_mains
where k.empname == "me"
select name
I much prefer the linq syntax like this for simple statements however:
var myDate = dc.emp_mains.where(w => w.empname == "me").Select(s => s.name).ToList();
Either way, you should get a list on names.

Custom Union in Linq to Entities

I need to union these rows on two ids without using an IEqualityComparer, as those are not supported in LINQ to Entities.
In result I need every unique combination of BizId and BazId, with the value from foos if the id pair came from there, else the value should be zero. This is a greatly simplified example and in reality these tables are very large and these operations cannot be done in memory. Because of this, this query needs to work with LINQ to Entities so that it can be translated to valid SQL and execute on the database. I suspect this can be done with some combination of where, join, and DefaultIfEmpty() instead of the Union and Distinct() but I am at a loss for now.
var foos = from f in Context.Foos where f.isActive select new { BizId = f.bizId, BazId = f.BazId, Value = f.Value };
var bars = from b in Context.Bars where b.isEnabled select new { BizId = b.bizId, BazId = b.BazId, Value = 0 };
var result = foos.Union(bars).Distinct(); //I need this to compare only BizId and BazId
You can group by the two fields and then get the first item of each group:
foos.Union(bars).GroupBy(x => new { x.bizId, x.bazId })
.Select(g => g.FirstOrDefault())

filtering a table by ids of another table in linq

So lets say i have a table mappedIds of an entity from linq, which has a relationship with another table named finishedDownloads on its column categoryID. How do i make a new table of mappedIds that contain no ids found in finishedDownloads?
I understand the commands like where and except, but im just not sure how to say, look at this id, and compare it to that id.
I'm looking for the equivalent of
SELECT * FROM mappedIds mIDs WHERE mIDs.CategoryID NOT IN
(SELECT categoryID FROM finishedDownloads)
Edit: Mapped Ids is stored in a Table
You didn't say how your context is set, but even if it's not exactly as I think it is you can easily see the idea:
var results = _context.MappedIds
.Where(x => !_context.FinishedDownloads
.Select(f => f.categoryID)
.Contains(x.CategoryID));
var idList = finishedDownloads.Select(f => f.categoryID);
var result = mappedIds.Where(m => !idList.Contains(m.CategoryID)).ToList();
Try this
var result = mappedIds.Select(m=>m.CategoryId).Except(finishedDownloads
.Select(f=>f.categoryId));

LINQ Group By to project into a non-anonymous type?

I have the following LINQ example:
var colorDistribution =
from product in ctx.Products
group product by product.Color
into productColors
select
new
{
Color = productColors.Key,
Count = productColors.Count()
};
All this works and makes perfect sense.
What I'm trying to achieve is to group by into a strong type instead of anonymous type.
For example I have a ProductColour class and I would like to Group into a List<ProductColour>
Is this possible?
Thank you
EDIT: Okay, I'd completely misread your post. By the looks of it, you're not wanting to group by a different type - you're wanting to project each element of the group into a different type. Here's what I'd do:
var colorDistributionSql =
from product in ctx.Products
group product by product.Color
into productColors
select
new
{
Color = productColors.Key,
Count = productColors.Count()
};
var colorDistributionList = colorDistributionSql
.AsEnumerable()
.Select(x => new ProductColour(x.Color, x.Count))
.ToList();
LinqToSql does allow direct projection of the group into a type (after all, the group is just an IGrouping<T, U>, a type). What LinqToSql can't do, is translate a constructor into SQL.
IQueryable<ProductColour> colorDistributionSql =
from product in ctx.Products
group product by product.Color
into productColors
select new ProductColour()
{
Color = productColors.Key,
Count = productColors.Count()
};

How do I get a distinct, ordered list of names from a DataTable using LINQ?

I have a DataTable with a Name column. I want to generate a collection of the unique names ordered alphabetically. The following query ignores the order by clause.
var names =
(from DataRow dr in dataTable.Rows
orderby (string)dr["Name"]
select (string)dr["Name"]).Distinct();
Why does the orderby not get enforced?
The problem is that the Distinct
operator does not grant that it will
maintain the original order of
values.
So your query will need to work like this
var names = (from DataRow dr in dataTable.Rows
select (string)dr["Name"]).Distinct().OrderBy( name => name );
To make it more readable and maintainable, you can also split it up into multiple LINQ statements.
First, select your data into a new list, let's call it x1, do a projection if desired
Next, create a distinct list, from x1 into x2, using whatever distinction you require
Finally, create an ordered list, from x2 into x3, sorting by whatever you desire
var sortedTable = (from results in resultTable.AsEnumerable()
select (string)results[attributeList]).Distinct().OrderBy(name => name);
Try out the following:
dataTable.Rows.Cast<DataRow>().select(dr => dr["Name"].ToString()).Distinct().OrderBy(name => name);
Try the following
var names = (from dr in dataTable.Rows
select (string)dr["Name"]).Distinct().OrderBy(name => name);
this should work for what you need.
To abstract: all of the answers have something in common.
OrderBy needs to be the final operation.
You can use something like that:
dataTable.Rows.Cast<DataRow>().GroupBy(g => g["Name"]).Select(s => s.First()).OrderBy(o => o["Name"]);

Categories