NHibernate query help needed - tsql

Is it possible to convert the following query into ICriteria or LINQ, and if so, how?
SELECT Test.personid
FROM
(
SELECT r.PersonId AS personid, e.ActivityId
FROM Event e
INNER JOIN Registration r ON e.Id = r.EventId
WHERE e.ActivityId IN (1, 2)
GROUP BY r.PersonId, e.ActivityId
) AS Test
GROUP BY Test.personid
HAVING COUNT(Test.ActivityId) >= 2

var result = from r in session.Query<Registration>()
where r.Event.ActivityId == 1 || r.Event.ActivityId == 2
group r by r.Person into g
where g.Min(x => x.Event.ActivityId) != g.Max(x => x.Event.ActivityId)
select g.Key
the following states, take all Persons wich have different activityIds in there groups which is equivalent to
ActivityId == 1 || ActivityId == 2
Having Count(r.Event.ActivityId) >= 2

Related

Linq Limit/Group by Id when joining IQueryables

I have a list of ids, that I then have multiple IQueryables that at the end I am joining to return my results. However some of these queries could have multiple records for that particular ID and I only need 1 record per ID from my set of x IDs. For example there could be 1 Name record, 3 Addresses, 2 Emails, 4 Phones for a single ID, but I only need 1 of each, does not matter which if multiple exist.
var clientNames = (
from n in db.Names
join cnl in db.ClientNameLinks on n.name_id equals cnl.name_id
where request.Ids.Contains(cnl.client_id)
&& n.name_id > 0
&& n.nametype_id != null
select new
{
n.display_name,
cnl.client_id
});
var clientAddresses = (
from a in db.Addresses
join cal in db.ClientAddressLinks on a.address_id equals cal.address_id
where request.Ids.Contains(cal.client_id)
&& a.address_id > 0
select new {
a.display_address,
cal.client_id
});
var clientEmails = (
from e in db.Emails
join cel in db.ClientEmailLinks on e.email_id equals cel.email_id
where request.Ids.Contains(cel.client_id)
&& e.email_id > 0
select new {
e.email_address,
cel.client_id
});
var clientPhones = (
from p in db.Phones
join cpl in db.ClientPhoneLinks on p.phone_id equals cpl.phone_id
where request.Ids.Contains(cpl.client_id)
&& p.phone_id > 0
select new {
p.phone_num,
cpl.client_id
});
var rows = await (
from n in clientNames
join a in clientAddresses on n.client_id equals a.client_id into n_a
from na in n_a.DefaultIfEmpty() //LEFT JOIN
join e in clientEmails on n.client_id equals e.client_id into n_e
from ne in n_e.DefaultIfEmpty() //LEFT JOIN
join ph in clientPhones on n.client_id equals ph.client_id into n_p
from np in n_p.DefaultIfEmpty() //LEFT JOIN
select new PiiDiamondClient
{
ClientId = n.client_id,
DisplayName = n.display_name,
DisplayAddress = na.display_address,
EmailAddress = ne.email_address,
PhoneExtension = np.phone_ext,
PhoneNumber = np.phone_num
}).Distinct().ToListAsync();
return rows.OrderBy(x => x.ClientId).ToList();
Your last query can be rewritten in the following way. It will exactly get one record from JOIN which can multiply result set.
var query =
from n in clientNames
from a in clientAddresses.Where(a => n.client_id == a.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
from e in clientEmails.Where(e => n.client_id == e.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
from ph in clientPhones.Where(ph => n.client_id == ph.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
select new PiiDiamondClient
{
ClientId = n.client_id,
DisplayName = n.display_name,
DisplayAddress = a.display_address,
EmailAddress = e.email_address,
PhoneExtension = ph.phone_ext,
PhoneNumber = ph.phone_num
};

Linq to SQL query with COALESCE in where clause

I am trying to convert the following sql query in to linq to sql (for entity framework)
select A.*, B.* from TABLE1 A
left join TABLE2 B
on A.LocationLoadPositionId = B.FkLocationLoadPositionId
where COALESCE(B.UploadStatus,0) = 0
So far I've got it to this far:
var positions = (from a in dbContext.TABLE1 join b in dbContext.TABLE2
on a.LocationLoadPositionId equals b.FkLocationLoadPositionId into c from d in c.DefaultIfEmpty()
where d.UploadStatus == false select new { a, d }).ToList();
The above linq query doens't seem to be working correctly because of my where condition... I am getting different result set for the two queries above... what am i missing here?...
Try this:
var positions = (from a in dbContext.TABLE1 join b in dbContext.TABLE2
on a.LocationLoadPositionId equals b.FkLocationLoadPositionId into c from d in c.DefaultIfEmpty()
where d.UploadStatus == false || d == null select new { a, d }).ToList();
Somethings like..
var positions = (from a in dbContext.TABLE1
join b in dbContext.TABLE2
on a.LocationLoadPositionId equals b.FkLocationLoadPositionId into c
let x = d.UploadStatus == 0 //<--- COALESCE
from d in c.DefaultIfEmpty()
where x == true).ToList();
return query.ToList();

How to do left join with group by in NET Core 3.0

As we know in .NET Core 3.0 a lot has changed and I'm building queries which don't run on client side memory.
I want to achieve a left join which count the items from child table keeping the parent intact if there no children against it.
Desired output query:
SELECT [c].[Type] AS [Name], COUNT([c0].Id) AS [Count]
FROM [CustomerTypes] AS [c]
LEFT JOIN [Customers] AS [c0] ON [c].[Id] = [c0].[CustomerTypeId]
WHERE [c0].[Id] IS NULL OR (([c0].[CompanyId] = 1) AND [c0].[CompanyId] IS NOT NULL)
GROUP BY [c].[Id], [c].[Type]
Entity Framework Queries
from types in _dbManager.CustomerTypes
join customers in _dbManager.Customers
on types.Id equals customers.CustomerTypeId into tempJoin
from leftJoined in tempJoin.DefaultIfEmpty()
where leftJoined == null || leftJoined.CompanyId == 1
group leftJoined by new { types.Id, types.Type } into grouped
select new TabCountBindingModel()
{
Name = grouped.Key.Type,
Count = grouped.Count(c => c != null)
}
Output Query
SELECT [c].[Type] AS [Name], COUNT(*) AS [Count]
FROM [CustomerTypes] AS [c]
LEFT JOIN [Customers] AS [c0] ON [c].[Id] = [c0].[CustomerTypeId]
WHERE [c0].[Id] IS NULL OR (([c0].[CompanyId] = 1) AND [c0].[CompanyId] IS NOT NULL)
GROUP BY [c].[Id], [c].[Type]
No matter what I try I always end up with query above, either this or an exception.
Tried these too
from types in _dbManager.CustomerTypes
join customers in _dbManager.Customers
on types.Id equals customers.CustomerTypeId into tempJoin
from leftJoined in tempJoin.DefaultIfEmpty()
where leftJoined == null || leftJoined.CompanyId == 1
group leftJoined by new { types.Id, types.Type } into grouped
select new TabCountBindingModel()
{
Name = grouped.Key.Type,
Count = grouped.Where(c=>c != null).Count()
}
Results in exception.

Select one record for group with Entity Framework Core method syntax

In Entity Framework Core I need to express the following SQL query by using the method syntax instead.
select *
from [Rule] as t1
where
(
select count(*)
from [Rule] as t2
where t1.ProductID = t2.ProductID
and t2.Priority > t1.Priority
) = 0
The query returns the records with the highest Priority for each ProductID.
Is there a way?
Thanks.
Try this :
var rules = db.Rules.Where(
a=>db.Rules.Where(
b => b.ProductId == a.ProductId && b.Priority > a.Priority
).Count() == 0
);
if you'd like use Linq syntax :
var rules = from a in db.Rules
where (
from b in db.Rules
where a.ProductId == b.ProductId
&& b.Priority > a.Priority
select b
).Count() == 0
select a;

LINQ to Entities: Convert SQL Sub Select

I got this figured out.
No need to answer.
The system says I have to wait 8 hours before answering my own questions. But for now the answer is below:
Here is the answer:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID),
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
}).ToList();
The key code was:
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
We are in the process of converting SQL / Stored Procedures to LINQ to Entities statements. And I can’t figure out the proper syntax for a sub select.
Currently I am converting this SQL:
declare #startDate DateTime
set #startDate = DATEADD(DD, -30, GETDATE())
select * from history where historyid in(
select MAX(h.historyid) as HistoryId
from History h (nolock)
inner join Quote q (nolock) on h.QuoteID = q.QuoteID
inner join Agency (nolock) a on q.AgencyID = a.AgencyID
inner join DC_PLT_EntityRoles er (nolock) on a.AgencyID = er.EntityID
inner join DC_PLT_Roles (nolock) r on er.RoleID = r.RoleID
where
q.Status = 'Inforce'
and q.LOB = 'Vacant'
and q.EffectiveDate > #startDate
and h.Deleted is null --
and h.DeprecatedBy is null --
and h.TransactionStatus = 'Committed'
and r.Name = 'Wholesaler'
group by h.PolicyNumber)
As you can see the code above is made up of two select statements. The main select (select * from history).. And a filter select (select MAX(h.historyid)…)
I got the filter select working (See below):
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID)
}).ToList();
However I can’t figure out the proper syntax to set up the main select. (Basically getting the records from the History table using the HistoryID from the filter select.)
Any help would be appreciated.
Thanks for your help.
I figured it out, here is the code:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
.Include("Quote")
.Include("Quote.Agency")
where h.Quote.Status == "Inforce" &&
h.Quote.LOB == "Vacant" &&
h.Quote.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
h.Quote.Agency.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
The key logic is:
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
Gotta love the Nested Query