Distinct record using linq in entity framework - c#

According to this query i get all records which have same id but i want only one time that record
var query = (from c in CompObj.EmpInfoes
join d in CompObj.Leaves on c.EmpID equals d.ProjectManagerID
where c.RoleID == 4 || c.RoleID == 2
select new { c.EmpName, c.EmpID });

var query = (from c in CompObj.EmpInfoes
join d in CompObj.Leaves on c.EmpID equals d.ProjectManagerID
where c.RoleID == 4 || c.RoleID == 2
select new { c.EmpName, c.EmpID })
.Distinct();
Or was there something more you needed?

Just add .Distinct() at the end.

Related

Add 'where' clausures dynamically to linq query

I have this linq query:
var query = (from dc in context.Table1.Include(d => d.Doc)
join u in _context.Table2 on dc.IDDoc equals u.IDDoc
where dc.ID == id && u.IDUser == user.IDUser
select dc)
.Union(from dc in context.Table1.Include(d => d.Doc)
join p in _context.Table3 on dc.IDDoc equals p.IDDoc
where dc.ID == id
select dc);
And I want to add more where conditions dynamically depends of a list (List ids)
What I want to achieve is something like this:
Imagine that I have a List ids = new(){1, 2, 5, 27);
What I want to do is to add that info into this part of the query to have something like this:
.Union(from dc in context.Table1.Include(d => d.Doc)
join p in _context.Table3 on dc.IDDoc equals p.IDDoc
where dc.ID == id && p.ID == 1 || p.ID == 2 || p.ID == 5 || p.ID = 27
select dc)
But if next time list is List ids = new(){4}, query should look like:
.Union(from dc in context.Table1.Include(d => d.Doc)
join p in _context.Table3 on dc.IDDoc equals p.IDDoc
where dc.ID == id && p.ID == 4
select dc)
Is it even possible? If not, what would be a possible solution?
Thank you
EDIT: I made up with this query because I have no clue about how to add it to my main query.
What I really have is this:
var mainQuery = _context.RootTable
.Include(i => i.Items).ThenInclude(dc => dc.Docs)
.Include(i => i.Items).ThenInclude(sg => sg.Signs)
.FirstOrDefault(m => m.ID== id);
And what I want to do is to filter the ".ThenInclude(dc => dc.Docs) with the other query. I can't figure out how to do it in a better and efficient way that with two sepparate queries.
Use Enumerable.Contains:
List<int> ids = new(){4};
....
.Union(from dc in context.Table1.Include(d => d.Doc)
join p in _context.Table3 on dc.IDDoc equals p.IDDoc
where dc.ID == id && ids.Contains(p.ID) // here
select dc)
....

inner join query in asp.net MVC4

I write query about search about specific employee but did'nt work ,I know there is an error in my query but did'nt now where it.
I have 2 tables one for company and another for employee info.
the progress will be:
1'st Query search in company table by department number and company
number then get the PK_companyID .
2'ed JOIN company.PK_companyID==employee.FK_companyID.
3'ed Query will search in employee table by FK_companyID when the
name enter will be the same in employee table.
I hope its Clear to understand
var query = (from c in db.Company
where c.departmentNO== departmentNumber && c.companyNo==companyNumber
join x in db.Employee c.PK_companyID==x.FK_companyID
where (x.FirstName.Contains(firstName ?? x.FirstName)
&& x.SecondName.Contains(secondName ?? x.SecondName)
&& x.ThirdName.Contains(thirdName ?? x.ThirdName)
&& x.FourthName.Contains(fourthName ?? x.FourthName))
select x).ToList();
Thank in advance.
You can simplify your query and your filtering by using code such below, should also result much cleaner SQL if you are not using all your filters.
var employees = (from c in db.Company
join e in db.Employee on c.PK_companyID equals e.FK_companyID
where c.departmentNO == departmentNumber && c.companyNo == companyNumber
select e);
if (!String.IsNullOrEmpty(firstName))
employees = employees.Where(pr => pr.FirstName.Contains(firstName));
if (!String.IsNullOrEmpty(secondName))
employees = employees.Where(pr => pr.SecondName.Contains(secondName));
if (!String.IsNullOrEmpty(thirdName))
employees = employees.Where(pr => pr.ThirdName.Contains(thirdName));
if (!String.IsNullOrEmpty(fourthName))
employees = employees.Where(pr => pr.FourthName.Contains(fourthName));
return employees.ToList();
var query = (from c in db.Company
join x in db.Employee c.PK_companyID == x.FK_companyID
where c.departmentNO == departmentNumber && c.companyNo == companyNumber
&& (x.FirstName.Contains(firstName ?? x.FirstName)
&& x.SecondName.Contains(secondName ?? x.SecondName)
&& x.ThirdName.Contains(thirdName ?? x.ThirdName)
&& x.FourthName.Contains(fourthName ?? x.FourthName))
select x).ToList();
You should use keyword "equals" instead of "==" in join as below:
var query = (from c in db.Company
join x in db.Employee c.PK_companyID equals x.FK_companyID
where c.departmentNO == departmentNumber && c.companyNo == companyNumber
.......
Hope this will work.

How can I write a linq query for this?

I need to write following query in Linq to SQL but not sure what is the best way of doing, given it has two derived tables. Any suggestions.
SELECT A.ID
FROM
(
SELECT *
FROM Orders
WHERE ProductID = 5
) A
JOIN
(
SELECT CustomerID, MAX(Price) Price
FROM Orders
WHERE ProductID = 5
GROUP BY CustomerID
) B
ON A.CustomerID = B.CustomerID and A.Price = B.Price
var b = (
from o in db.Orders
where o.ProductID == 5
group o by o.CustomerID into og
select new {
CustomerID = og.Key
Price = Max(og.Price)
}
);
var a = (
from o in db.Orders
join p in b on new {a.CustomerID, a.Price} equals
new {b.CustomerID, b.Price}
where o.ProductID == 5
select a.ID
);
var r = a.ToString();
These two links are invaluable when forming things like this:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
http://msdn.microsoft.com/en-us/vstudio/bb688085
Can you simplify this with LINQ, especially if you use method syntax instead of query syntax.
orders.Where(o => o.ProductID == 5)
.GroupBy(o => o.CustomerID)
.SelectMany(g => g.Where(o => o.Price == g.Max(m => m.Price)));
My advice when writing LINQ, do not simply attempt to convert a SQL statement exactly. Think about the desired result and develop a solution designed for LINQ.
Something along these lines:
var result = from a in context.Orders
join b in (context.Orders.Where(o => o.ProductID == 5).GroupBy(o => o.CustomerID).Select(g => new { CustomerID = g.Key, Price = g.Max(o => o.Price)))
on new {a.CustomerID, a.Price} equals new {b.CustomerID, b.Price}
where a.ProductID == 5
select a.ID;

modify linq to get first 5 elements

var lastArticles = from a in be.MyTable
where a.id == 1
join c in be.OtherTable on a.parent equals c.id
orderby a.timestamp descending
select new { a, cName = c.name};
I need to get the first 5 elements.
I'm doing it by
.Take(5)
but is there a way to do in in the linq statement?
No, you need to use Skip() and Take() as method calls. There is no LINQ-specific equivalent.
var lastArticles = (from a in be.MyTable
where a.id == 1
join c in be.OtherTable on a.parent equals c.id
orderby a.timestamp descending
select new { a, cName = c.name }).Take(5);
A linq Query should always be separate from the products of running that query.
.Take() produces results, and thus should be separate and distinct from the query.
//data query
var lastArticlesQuery = from a in be.MyTable
where a.id == 1
join c in be.OtherTable on a.parent equals c.id
orderby a.timestamp descending
select new { a, cName = c.name};
//results of that query at this time
var lastArticles = lastArticlesQuery.Take(5);
This code is only syntatic sugar, utlimately it will be converted to a LINQ-methods chain that will look something like:
var lastArticles = be.MyTable
.Where(a => a.id == 1)
.Join(be.OtherTable, a => a.parent, c => c.id,
(a, c) => new { a, c})
.OrderByDescending(#t => #t.a.timestamp)
.Select(#t => new { #t.a, cName = #t.c.name });
So having a keyword for Take() would only add to the sytactic sugar and it would need to be re-converted as well.
In short, no, the only way is to use the Take() method.

Efficient way to sub Queries in Linq

here is my linq code:
BOOK entity = db.BOOKS
.Where(s => s.ID == (from p in db.LIBRARY
from b in db.BOOKS
where (p.ID == 123) && (p.idpage == b.idpage)
select b.fields));
My actual oracle code is:
SELECT DISTINCT BOOKS.ID
FROM LIBRARY,BOOKS
WHERE LIBRARY.ID = 123 AND LIBRARY.ID = BOOKS.ID
But its showing the error in s.ID that..
Delegate 'System.Func Project.Models.BOOKS,int,bool' does not take 1 arguments
Why does this happen? Are there any workarounds?
Your SQL is using a join, so you can do the same thing in LINQ. Either of these approaches will suffice:
// join
var query = (from b in db.BOOKS
join p in db.LIBRARY on b.IdPage equals p.IdPage
where p.ID == 123
select b.Id).Distinct();
// 2 from statements (SelectMany) can also be used as a join
var query = (from b in db.BOOKS
from p in db.LIBRARY
where p.ID == 123 && b.IdPage == p.IdPage
select b.Id).Distinct();
// fluent syntax
var query = db.BOOKS
.Where(b => db.LIBRARY.Any(p =>
p.ID == 123 && b.IdPage == p.IdPage))
.Select(b => b.Id)
.Distinct();
s.ID is comparing to an Enumerable, so you get the error.
At the end of the LINQ query, add a SingleOrDefault().
Your subquery returns a sequence of values, not a single values, so you can't compare it to a scalar property like ID. You should use First on the result of the subquery to get the first result (or Single if there should be only one)
BOOK entity = db.BOOKS
.Where(s => s.ID == (from p in db.LIBRARY
from b in db.BOOKS
where (p.ID == 123) && (p.idpage == b.idpage)
select b.fields).First());
You should be able to use the navigation properties on your BOOKS class to do something like this:
var bookIds = db.BOOKS.Where(b => b.LIBRARIES.Any(l => l.ID == 123))
.Select(b => b.ID)

Categories

Resources