Having problems with writing sql query on linq - c#

I have an SQL query which returns all accounts and in the top of the result table I have accounts which share same documents. Query below works just fine, but there is a problem implementing the same logic on linq.
select
(
select
COUNT(*)
from Signs X, Signs Y
where X.AccountID = 2 and Y.AccountID = A.ID and X.DocID = Y.DocID
),
*
from
Accounts A
where
A.ID != 2
order by 1 desc

var result = from A in Accounts
where A.ID != 2
select new { Count = (from X in Signs
from Y in Signs
where X.AccountID == 2 &&
Y.AccountID == A.ID &&
X.DocID == Y.DocID
select 1).Count(),
A };
Note: You could probably change the subquery to a join on DocID but i've left as is, so you can see the similarity between the SQL and the LINQ.
Example with a join:
var result = from A in Accounts
where A.ID != 2
select new { Count = (from X in Signs
join Y in Signs on X.DocID equals Y.DocID
where X.AccountID == 2 &&
Y.AccountID == A.ID
select 1).Count(),
A };

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();

how can I use average function usage with Count function in Linq to EF

I would like to use Average function with Count in my Linq to EF query. So if I have to explain what I try to realize with my code part in t-sql for more clear understanding, You can take look below them,
select s.SalesPointId, count(*) as ipp
from ScoreItem si
inner join Score s on s.Id = si.ScoreId
where si.ResearchGroupType = 0 and si.IsValidForSalesPoint = 1
group by s.SalesPointId
select avg(ipp)
from (
select s.SalesPointId, count(*) as ipp
from ScoreItem si
inner join Score s on s.Id = si.ScoreId
where si.ResearchGroupType = 0 and si.IsValidForSalesPoint = 1
group by s.SalesPointId
)
As a consequence I have wrote below code in Linq query,
List<CvmNameAndValue> AnatolianSalesHeadshipIPPScore = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && si.IsValidForSalesPoint && sp.CompanyId == ContextData.User.CompanyId && s.ProjectPeriodId == ProjectPeriodId && spIds.Contains(sp.Id))
group s by s.SalesPointId into g
select new CvmNameAndValue
{
Name = SystemSetting.Label_AnatolianSalesHeadshipIPPScore,
Value = g.Average(x => db.Score.Count()).ToString()
})
.ToList();
retVal.Data.DataGroup = AnatolianSalesHeadshipIPPScore.ToList();
return retVal;
But, Unfortunately they didn't return same result for me, so if you have any suggestion about my logic mistakes, please feel to free and share with me,
Finally I have solved my problem, so if you need such as thing, it can be solve your problem,
double AnatolianSalesHeadshipIPPScore = 0;
AnatolianSalesHeadshipIPPScore = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && si.IsValidForSalesPoint && sp.CompanyId == ContextData.User.CompanyId && s.ProjectPeriodId == ProjectPeriodId)
group si by s.SalesPointId into g
select new
{
sid = g.Key,
count = g.Count()
}).Average(m => m.count);

Wrting a SQL query in LINQ

I have this so far:
var query = (from g in this.Context.Groups
where g.ID == groupID &&
g.TaxId == groupTaxId
select g.Group_K);
Then the SQL query I want to add is this:
select zipCode from ADDRESSES where ADDRESS_K in
(select ADDRESS_K from GROUPADDRESS
where GROUP_K = "is in Group_K found above "
and address_type = "address type variable I pass into this method"
and ACTIVE = 1)
I can't figure it out how to add a new LINQ query or update the one I have to account for the new SQL I am trying to add. Thanks for help.
How about this one?
var group_key = (from g in this.Context.Groups
where g.ID == groupID
&& g.TaxId == groupTaxId
select g.Group_K);
var query = (from a in this.Context.Addresses
join ga in this.Context.GroupAddress on a.Address_K equals ga.Address_K
where (group_key.Contains(ga.Group_K) && a.ZipCode == "whatever passed from method" && ga.Address_Type == "whatever passed from your method")
select a);
IN statement is equivalent to Contains method call in LINQ to Entities:
var query = from a in this.Context.Addresses
where (from g in this.Context.Groups
where g.ID == groupID && g.TaxId == groupTaxId
select g.Group_K).Contains(a.Address_K);
select a.ZipCode;
You could also rewrite your query to use JOIN instead of nested queries:
var query = from a in this.Context.Addresses
join g in this.Context.Groups on a.Address_K equals g.Group_K
where g.ID == groupID && g.TaxId == groupTaxId
select a.ZipCode;

How to Use Data Inside Var in Linq?

I want to sum records using Group by from the all data inside "result view".
can anyone guide me for this.!
Here is My Code
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select g.OrderByDescending(t => t.DateCreated)).ToList();
foreach (var xCo in tData1)
{
//I am getting Data in xCo
}
Based on #Nayeem Mansoori solution you can try this.
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select new {Id = DeviceInfoId, sum = g.Sum(x=>x.DeviceInfoId)};

Linq Sub-Select

How do I write a sub-select in LINQ.
If I have a list of customers and a list of orders I want all the customers that have no orders.
This is my pseudo code attempt:
var res = from c in customers
where c.CustomerID ! in (from o in orders select o.CustomerID)
select c
How about:
var res = from c in customers
where !orders.Select(o => o.CustomerID).Contains(c.CustomerID)
select c;
Another option is to use:
var res = from c in customers
join o in orders
on c.CustomerID equals o.customerID
into customerOrders
where customerOrders.Count() == 0
select c;
Are you using LINQ to SQL or something else, btw? Different flavours may have different "best" ways of doing it
If this is database-backed, try using navigation properties (if you have them defined):
var res = from c in customers
where !c.Orders.Any()
select c;
On Northwind, this generates the TSQL:
SELECT /* columns snipped */
FROM [dbo].[Customers] AS [t0]
WHERE NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Orders] AS [t1]
WHERE [t1].[CustomerID] = [t0].[CustomerID]
))
Which does the job quite well.
var result = (from planinfo in db.mst_pointplan_info
join entityType in db.mst_entity_type
on planinfo.entityId equals entityType.id
where planinfo.entityId == entityId
&& planinfo.is_deleted != true
&& planinfo.system_id == systemId
&& entityType.enity_enum_id == entityId
group planinfo by planinfo.package_id into gplan
select new PackagePointRangeConfigurationResult
{
Result = (from planinfo in gplan
select new PackagePointRangeResult
{
PackageId = planinfo.package_id,
PointPlanInfo = (from pointPlanInfo in gplan
select new PointPlanInfo
{
StartRange = planinfo.start_range,
EndRange = planinfo.end_range,
IsDiscountAndChargeInPer = planinfo.is_discount_and_charge_in_per,
Discount = planinfo.discount,
ServiceCharge = planinfo.servicecharge,
AtonMerchantShare = planinfo.aton_merchant_share,
CommunityShare = planinfo.community_share
}).ToList()
}).ToList()
}).FirstOrDefault();
var res = (from c in orders where c.CustomerID == null
select c.Customers).ToList();
or Make Except()

Categories

Resources