How to do multiple Select Where in Linq - c#

I'm new in Linq, and I want to convert this sql Query to Linq Format.
This is the SQL format
select *
from investorwallets iw
where transactionid in
(select investordepositid from investordeposits)
or transactionid in
(select withdrawalid from investorwithdrawals)
or transactionid in
(select paymentdistributionid from paymentdistributions)
I've looked on this SO Question too, but no luck for me
EDIT
This is what I have tried. I use Linqpad for testing it
from iw in Investorwallets
where (
from id in Investordeposits // I got error from here
select id.investordepositid
)
Anyone can help me?
Thank you

The most direct is:
from iw in investorwallets
where investordeposits.Any(iten => item.investordepositid == iw.transactionid) ||
investorwithdrawals.Any(iten => item.withdrawalid == iw.transactionid) ||
paymentdistributions.Any(item => item.paymentdistributionid == iw.transactionid)
select iw;
However you can also union the results and then do .Contains:
var ids = investorwithdrawals.Select(item => item.investordepositid)
.Union(investorwithdrawals.Select(item => item.withdrawalid))
.Union(paymentdistributions.Select(item => item.paymentdistributionid));
var result = investorwallets.Where(item => ids.Contains(item.transactionid));

List<investorwallet> investorwallets = GetInvestorwallets();
List<investordeposit> investordeposits = GetInvestordeposits();
List<investorwithdrawal> investorwithdrawals = GetInvestorwithdrawals();
List<paymentdistribution> paymentdistributions = GetPaymentdistribution();
List<investorwallet> newList = investorwallets.Where(x => investordeposits.Any(y=>y.investordepositid == x.transactionid)
|| investorwithdrawals.Any(y => y.withdrawalid == x.transactionid)
|| paymentdistributions.Any(y => y.paymentdistributionid == x.transactionid)).ToList();

Related

Perform SELECT statement on another SELECT using LINQ

In my .NET Core app, I have the following in LINQ:
return await db.ApplicationUsers.Where(u=>u.Name.Contains(name) && !u.Deleted && u.AppearInSearch)
.OrderByDescending(u => u.Verified)
.Skip(page * recordsInPage)
.Take(recordsInPage)
.Select(u => new UserSearchResult()
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
}).ToListAsync();
which translates to the following SQL:
SELECT [t].[Name], [t].[Verified],
[t].[PhotoURL], [t].[Id],
[t].[Subdomain]
FROM
(SELECT [u0].*
FROM [AspNetUsers] AS [u0]
WHERE (((CHARINDEX('khaled', [u0].[Name]) > 0) OR ('khaled' = N''))
AND ([u0].[Deleted] = 0))
AND ([u0].[AppearInSearch] = 1)
ORDER BY [u0].[Verified] DESC
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY ) AS [t]
But due to performance issues, Microsoft support suggested that I only query columns of fixed length (not varchar(max)). I was asked to change the SQL query to:
SELECT [t].[Name], [t].[Verified],
[t].[PhotoURL] , [t].[Id], [t].[Subdomain]
FROM
(Select u0.Name, u0.Verified, u0.PhotoURL, u0.id, u0.Subdomain,
u0.Deleted, u0.AppearInSearch FROM [AspNetUsers] ) As [u0]
WHERE (((CHARINDEX('khaled', [u0].[Name]) > 0) OR ('khaled' = N''))
AND ([u0].[Deleted] = 0))
AND ([u0].[AppearInSearch] = 1)
ORDER BY [u0].[Verified] DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY ) AS [t]
Which is a SELECT on another SELECT. Unfortunately I don't know how to do it in LINQ. Can someone please guide me how to make the second SQL query in LINQ?
Thank you
First build the inner select:
var s1 = from u in db.AspNetUsers
select new UserSearchResult
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
};
then use it in the outer select:
return await (from u1 in s1
where u.Name.Contains(name) && !u.Deleted && u.AppearInSearch
orderby u.Verified
select u1)
.Skip(page * recordsInPage)
.Take(recordsInPage);
When you make the output of select query .ToList(), the output is a list again. Over this list you can apply another .Select(). So, as in your previous query, you can do it as:
return await db.ApplicationUsers.Where(u=>u.Name.Contains(name) && !u.Deleted && u.AppearInSearch)
.OrderByDescending(u => u.Verified)
.Skip(page * recordsInPage)
.Take(recordsInPage)
.Select(u => new UserSearchResult()
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
})
.ToList()
.Select(<your new query>)
.ToListAsync();

Method MAX() from SQL to Linq

Hi i'm trying to convert this SQL script in Linq expression
but i donĀ“t know how do the MAX method in Linq
someone can help me?
thank you!
SELECT c.Nome,
c.NumeroRG,
f.Tipo,
f.Descricao,
f.DataHora,
f.IdCliente,
c.IdCliente,
f.IdFrequencia
FROM Cliente c, Frequencia f
WHERE f.Tipo = 1
AND c.IdCliente = f.IdCliente
AND cast(f.DataHora as date) = cast(getdate() as date)
AND f.IdFrequencia = (select MAX(fr.IdFrequencia)
from frequencia fr
where fr.IdCliente =c.IdCliente)
Perhaps something like this:
var query = from client in db.Cliente
join freq in db.Frequencia
on client.IdCliente equals freq.IdCliente
where freq.Tipo == 1
&& freq.DataHora.Date == DateTime.Now.Date
&& freq.IdFrequencia == db.Frequencia.Where(f => f.IdCliente == client.IdCliente)
Max(f => f.IdFrequencia)
select new { .... };
Maybe you need to replace DateTime.Now.Date/DateTime.Today with SqlFunctions.DatePart if you use LINQ-To-Entities, but you haven't mentioned that.
this worked well! thanks
var query = from client in db.Cliente
join freq in db.Frequencia
on client.IdCliente equals freq.IdCliente
where freq.Tipo == true
&& freq.DataHora.Value.Date == DateTime.Today.Date
&& freq.IdFrequencia == db.Frequencia.Where(f => f.IdCliente == client.IdCliente).Max(f => f.IdFrequencia)
select new { Nome = client.Nome, Descricao = freq.Descricao };

Select with NOT IN with entity framework

I am trying to take the SQL code below and turn turn it into an EF select statement. I pretty much have it finished except I am stuck on how to do a NOT IN in entity framerwork.
MS SQL SELECT
SELECT * from friends as f
WHERE (f.id NOT IN (Select friendid from users_friends where userid = 1))
AND (f.lastname LIKE '%b%' OR f.firstname LIKE '%b%' OR f.alias LIKE '%b%')
My EF select without the NOT IN part
var friends =
(from f in db.Friends
select new FriendModel()
{
Id = f.Id,
Alias = f.Alias,
CarrierId = f.CarrierId,
CreatedOn = f.CreatedOn,
FirstName = f.FirstName,
LastName = f.LastName,
Locked = f.Locked,
PhoneNumber = f.PhoneNumber,
SteamId = f.SteamId,
Carrier = new CarrierModel()
{
CarrierName = f.Carrier.CarrierName,
CarrierEmail = f.Carrier.CarrierEmail
}
}).Where(
f => (f.Alias.Contains(query) || f.FirstName.Contains(query) || f.LastName.Contains(query)))
.OrderBy(f => f.Alias)
.ToList();
I guess this is what you want:
var friendIds = db.users_friends.Where(f => f.userid == 1).Select(f => f.friendid);
var friends = db.Friends.Where(f => !friendIds.Contains(f.Id) &&
(f.Alias.Contains(query) ||
f.FirstName.Contains(query) ||
f.LastName.Contains(query)))
.Select(f => new FriendModel() { ... })
.OrderBy(f => f.Alias)
.ToList();
Assuming User entity has a collection of Friend entity.
.Where(f => (f.Alias.Contains(query) || f.FirstName.Contains(query) || f.LastName.Contains(query))
&& !context.Users.FirstOrDefault(u=>u.UserId == 1)
.Friends.Any(uf=>uf.FriendId == f.FriendId))
If not, query the UserFriend table directly
.Where(f => (f.Alias.Contains(query) || f.FirstName.Contains(query) || f.LastName.Contains(query))
&& !context.UserFriends.Any(uf=>uf.UserId == 1 && uf.FriendId == f.FriendId)

LINQ query with sub where clause

I have a SQL query :
SELECT [Paypoint]
,[Department]
,[EmployeeCode]
,[Gender]
,[EmployeeTitle]
,[Initials]
,[Surname]
,[ItemsIssuedDate]
,[ItemsIssuedStockNumber]
FROM [MyTable] AS a
WHERE
(
[ItemsIssuedDate] = ( SELECT max([ItemsIssuedDate])
FROM [MyTable] AS b
WHERE a.[Paypoint] = b.[Paypoint]
AND a.[Department] = b.[Department]
AND a.[EmployeeCode] = b.[EmployeeCode]
AND a.[Gender] = b.[Gender]
AND a.[Surname] = b.[Surname]
)
How would one get the comparitive LINQ query ? I cannot use the SQL query as the Data is already in a DataSet, and now needs to be modified further...
I have attempted, but this does not work :
var query = from a in excelTable
where
(
from c in excelTable
group c by new
{
c.Paypoint,
c.EmployeeCode
} into g
where string.Compare(a.Paypoint, g.Key.Paypoint) == 0 && string.Compare(a.EmployeeCode, g.Key.Paypoint) == 0
select g.Key.Paypoint
)
select a;
var query = from a in MyTable
group a by new {
a.Paypoint,
a.Department,
a.EmployeeCode,
a.Gender,
a.Surname
} into g
select g.OrderByDescending(x => x.ItemsIssuedDate)
//.Select(x => new { required properties })
.First();
You can also select anonymous object with required fields only. Up to you.
Your most direct with the SQL query will be:
var query =
from a in excelTable
let maxIssueDate =
(from b in excelTable
where a.Paypoint == b.Paypoint &&
a.Department == b.Department &&
a.EmployeeCode == b.EmployeeCode &&
a.Gender == b.Gender &&
a.Surname == b.Surname
select b.ItemsIssueDate).Max()
where a.ItemsIssueDate == maxIssueDate
select a;

How can I use over by partition in LINQ?

I'm confused about how to change this query to LINQ
select
CONTENT
from
(
select
CONTENT,
CAM_ID,
max(CAM_ID) over (partition by DOCUMENT_ID) MAX_ID
from
T_CAM_REVISION
where
DOCUMENT_ID = '101'
)
where
CAM_ID = MAX_ID
so I can get a single value of content.
There is no way to do max(...) over (...) in LINQ. Here is an equivalent query:
var maxCamID =
context.T_CAM_REVISION
.Where(rev => rev.DOCUMENT_ID == "101")
.Max(rev => rev.CAM_ID);
var query =
from rev in context.T_CAM_REVISION
where rev.CAM_ID == maxCamID
where rev.DOCUMENT_ID == "101"
select rev.CONTENT;
If you want only a single result:
var result =
context.T_CAM_REVISION
.First(rev => rev.CAM_ID == maxCamID
&& rev.DOCUMENT_ID == "101")
.CONTENT;

Categories

Resources