Fast join on Multiple IEnumerable - c#

Whith s_records, q_records, d_records, i_records all of type IEnumerable<MyRecord>, querytwo works just as expected. But what if I want to join multiple IEnumerable on the same equality of the same fields?
var querytwo = from a in s_records
join b in q_records
on a.date equals b.date
select new { s_line = a.line, q_line = b.line };
Console.WriteLine(querytwo.Count());
This query doesn't work I am trying to do the same as in querytwo, but join on multiple IEnumerable<MyRecord>:
var query = from a in s_records
join b in q_records
join c in d_records
join d in i_records
on a.date equals b.date equals c.date equals d.date
select new { s_line = a.line, q_line = b.line, d_line = c.line, i_line = d.line };

Your syntax is to off to some extent. it should be:
var querytwo = from a in s_records
join b in q_records on a.date equals b.date
join c in d_records on b.date equals c.date
join d in i_records on c.date equals d.date
select new {
s_line = a.line,
q_line = b.line,
d_line = c.line,
i_line = d.line
};

Related

How to change query to Entity Framework

I want to change this SQL query to Entity Framework query:
SELECT
dbo.ClassTiming.StartTime,
dbo.ClassTiming.EndTime,
dbo.Employee.StaffName,
dbo.Department.DepartmentName,
dbo.Class.ClassName,
dbo.Section.SectionName,
dbo.WeekDay.DayName
FROM dbo.Timetable
INNER JOIN dbo.ClassTiming
ON dbo.Timetable.ClassTimingId = dbo.ClassTiming.Id
INNER JOIN dbo.Employee
ON dbo.Timetable.StaffId = dbo.Employee.StaffID
INNER JOIN dbo.Department
ON dbo.Timetable.DepartmentId = dbo.Department.id
INNER JOIN dbo.Section
ON dbo.Timetable.SectionID = dbo.Section.ID
INNER JOIN dbo.Class
ON dbo.Timetable.ClassID = dbo.Class.ID
INNER JOIN dbo.WeekDay
ON dbo.Timetable.WeekDayId = dbo.WeekDay.Id
This should work
var db = new YourDbContext();
var result = (from t in db.Timetables
join c in db.ClassTimings on t.ClassTimingId equals c.Id
join e in db.Employees on t.StaffId equals e.StaffID
join d in db.Departments on t.DepartmentId equals d.Id
join s in db.Sections on t.SectionID equals s.Id
join cl in db.Classes on t.ClassID equals cl.Id
join w in db.WeekDays on t.WeekDayId equals w.Id
select
new { c.StartTime,
c.EndTime, e.StaffName,
d.DepartmentName,
cl.ClassName,
s.SectionName,
w.DayName
}
).ToList();

Linq With Entities List within Distinct List

I have a SQL Query that gets Distinct rows of Vendor Contacts, which is returning the proper number of rows:
SELECT DISTINCT v.VendorID, c.ContactID,
v.VendorName,
c.FirstName, c.MiddleName, c.LastName,
FROM VendorContacts vc
INNER JOIN Contact c
ON c.ContactID = vc.ContactID
INNER JOIN Vendor v
ON v.VendorID = vc.VendorID
LEFT JOIN [ContactServices] psvc
ON psvc.ContactID = c.ContactID
AND psvc.VendorID = v.VendorID
I have a method that I want to return of custom type, based on the above query:
public List<ProviderContactInfo> GetProviderContactInfo(ProviderContactInfo searchInfo)
{
using (var db = new MyContext())
{
var providerContactInfo =
(from vc in db.VendorContacts
join ps in db.ContactServices on new { vc.ContactID, vc.VendorID } equals new { ps.ContactID, ps.VendorID } into ps_join
from ps in ps_join.DefaultIfEmpty()
join c in db.Contacts on vc.ContactID equals c.ContactID
join v in db.Vendors on vc.VendorID equals v.VendorID
orderby vc.ContactID descending
select new ProviderContactInfo()
{
VendorName = v.VendorName,
FirstName = c.FirstName,
MiddleName = c.MiddleName,
LastName = c.LastName,
Services = (from o in db.ContactServices
join cps in db.Contacts on o.ContactID equals cps.ContactID
join vps in db.Vendors on o.VendorID equals vps.VendorID
join s in db.Services on o.ServiceID equals s.ServiceID
where ps.ServiceID == o.ServiceID
&& o.ContactID == c.ContactID
&& o.VendorID == v.VendorID
select s).ToList()
}).Distinct().ToList();
return providerContactInfo;
}
}
I'm getting the error:
Additional information: The 'Distinct' operation cannot be applied to
the collection ResultType of the specified argument.
Everything works fine when I remove the Services property from the new ProviderContactInfo so I'm sure it's in the way I'm trying to populate that property (which is of type List<Service>)
I know there are a lot of questions regarding Linq with Distinct etc but I couldn't find anything on this specific problem.
Please help!
EDIT This code works:
public List<ProviderContactInfo> GetProviderContactInfo(ProviderContactInfo searchInfo)
{
using (var db = new MyContext())
{
var providerContactInfo =
(from vc in db.VendorContacts
join c in db.Contacts on vc.ContactID equals c.ContactID
join v in db.Vendors on vc.VendorID equals v.VendorID
orderby vc.ContactID descending
select new ProviderContactInfo()
{
VendorName = v.VendorName,
FirstName = c.FirstName,
MiddleName = c.MiddleName,
LastName = c.LastName,
Services = (from o in db.ContactServices
join cps in db.Contacts on o.ContactID equals cps.ContactID
join vps in db.Vendors on o.VendorID equals vps.VendorID
join s in db.Services on o.ServiceID equals s.ServiceID
where o.ContactID == c.ContactID
&& o.VendorID == v.VendorID
select s).ToList()
}).Distinct().ToList();
return providerContactInfo;
}
}
You should add one more step to the process, to avoid applying Distinct() on the objects that have a collection (Services) property, the LINQ provider does not know how to handle it.
var providerContactInfo = from vc in db.VendorContacts
join ps in db.ContactServices on new { vc.ContactID, vc.VendorID } equals new { ps.ContactID, ps.VendorID } into ps_join
from ps in ps_join.DefaultIfEmpty()
join c in db.Contacts on vc.ContactID equals c.ContactID
join v in db.Vendors on vc.VendorID equals v.VendorID
orderby vc.ContactID descending
group ps by new
{
v.VendorName,
c.FirstName,
c.MiddleName,
c.LastName,
c.ContactID,
v.VendorID
} into g
select new ProviderContactInfo()
{
VendorName = g.Key.VendorName,
FirstName = g.Key.FirstName,
MiddleName = g.Key.MiddleName,
LastName = g.Key.LastName,
Services = (from e in g
from o in db.ContactServices
join cps in db.Contacts on o.ContactID equals cps.ContactID
join vps in db.Vendors on o.VendorID equals vps.VendorID
join s in db.Services on o.ServiceID equals s.ServiceID
where e.ServiceID == o.ServiceID
&& o.ContactID == g.Key.ContactID
&& o.VendorID == g.Key.VendorID
select s).ToList()
}
Wouldn't this be much simplier:
public IQueryable<VendorContact> GetProviderContactInfo(ProviderContactInfo searchInfo)
{
using (var db = new MyContext())
{
return providerContactInfo=db.VendorContacts
.Include(vc=>vc.Contacts)
.Include(vc=>vc.Services)
.Include(vc=>vc.Vendor)
.OrderByDescending(vc=>vc.ContactID);
}
}

How to Join LINQ to another LINQ

i have a query like this
WITH CTE_KELOMPOKINFORMASI (KelompokInformasi, XBRLItem_ItemId)
AS (
SELECT a.Id AS KelompokInformasi, c.XBRLItem_ItemId
FROM XBRLNamespaces a INNER JOIN XBRLHypercubes b
ON a.XBRLView_ViewId = b.XBRLView_ViewId
INNER JOIN XBRLHypercubeDimensionItems c
ON b.XBRLHypercubeId = c.XBRLHypercube_XBRLHypercubeId
WHERE a.Id like '%KBIK_AAKL%')
SELECT f.KelompokInformasi, e.Name AS DimensionName, c.Id AS Domain,
d.Text AS Description FROM [dbo].[XBRLDefinitionRoleDomainItems] a
INNER JOIN [dbo].[XBRLDefinitionRoleDimensionItems] b
ON a.XBRLDefinitionRole_DefinitionRoleId = b.XBRLDefinitionRole_DefinitionRoleId
INNER JOIN XBRLItems c ON a.XBRLItem_ItemId = c.ItemId
INNER JOIN XBRLLabels d
ON a.XBRLItem_ItemId = d.XBRLItem_ItemId
INNER JOIN XBRLItems e
ON b.XBRLItem_ItemId=e.ItemId
INNER JOIN CTE_KELOMPOKINFORMASI f
ON b.XBRLItem_ItemId=f.XBRLItem_ItemId
WHERE b.XBRLItem_ItemId=f.XBRLItem_ItemId
i want to move this sql query to linq, i realized that CTE is impossible in LINQ. So i divide into 2 parts. First i create a var like this:
var KelompokInformasi = from x in ent.XBRLNamespaces
join y in ent.XBRLHypercubes on x.XBRLView_ViewId equals y.XBRLView_ViewId
join z in ent.XBRLHypercubeDimensionItems on y.XBRLHypercubeId equals z.XBRLHypercube_XBRLHypercubeId
where x.Id.Contains("KBIK")
select new
{
x.Id,
y.XBRLItem_ItemId
};
and in second part i create:
_list = (from a in ent.XBRLDefinitionRoleDomainItems
join b in ent.XBRLDefinitionRoleDimensionItems on a.XBRLDefinitionRole_DefinitionRoleId equals b.XBRLDefinitionRole_DefinitionRoleId
join c in ent.XBRLItems on a.XBRLItem_ItemId equals c.ItemId
join d in ent.XBRLLabels on a.XBRLItem_ItemId equals d.XBRLItem_ItemId
join e in ent.XBRLItems on b.XBRLItem_ItemId equals e.ItemId
join f in KelompokInformasi on b.XBRLItem_ItemId equals (int)f.XBRLItem_ItemId
where (b.XBRLItem_ItemId == (int)f.XBRLItem_ItemId)
select new MappingDomainRepository
{
KI = f.Id,
Dimension = e.Name,
Domain = c.Id,
Description = d.Text
}).ToList();
Where _list is from List<MappingDomainRepository> _list = new List<MappingDomainRepository>();
in my code above, i want to join my _list to var KelompokInformasi. In var kelompokInformasi I've got 47 rows but in _list I've got 0 data return.
What's wrong in my code? is it possible to join my _list to var kelompokInformasi?
You need to change the second part to:
var other = (from a in ent.XBRLDefinitionRoleDomainItems
join b in ent.XBRLDefinitionRoleDimensionItems on a.XBRLDefinitionRole_DefinitionRoleId equals b.XBRLDefinitionRole_DefinitionRoleId
join c in ent.XBRLItems on a.XBRLItem_ItemId equals c.ItemId
join d in ent.XBRLLabels on a.XBRLItem_ItemId equals d.XBRLItem_ItemId
join e in ent.XBRLItems on b.XBRLItem_ItemId equals e.ItemId
join f in KelompokInformasi on b.XBRLItem_ItemId equals (int)f.XBRLItem_ItemId
where (b.XBRLItem_ItemId == (int)f.XBRLItem_ItemId)
select new MappingDomainRepository
{
KI = f.Id,
Dimension = e.Name,
Domain = c.Id,
Description = d.Text,
XBRLItem_ItemId = a.XBRLItem_ItemId
};
...which adds in the XBRLItem_ItemId which use to join to the CTE.
Then join the two together. We have other (above) and KelompokInformasi from the CTE:
var result = from x in KelompokInformasi
join o in other on x.XBRLItem_ItemId equals o.XBRLItem_ItemId
select new {KelompokInformasi = o.KelompokInformasi,
DimensionName = o.Name,
Domain = o.Id,
Description = o.Text
};
..which appears to be the columns you exentually select.

LINQ to Entities multiple join

Hi im trying to replicate this mysql query
SELECT a.id, a.title, a.description, a.categories_id, c.name, d.title
FROM ads AS a
INNER JOIN locations AS b
ON a.locations_id = b.id
INNER JOIN areas AS c
ON b.areas_id = c.id
INNER JOIN categories AS d
ON a.categories_id = d.id
WHERE a.title LIKE '%mini%'
AND c.name = 'Fyn'
LIMIT 10
and here is it in LINQ
var query = (from a in db.ads
join b in db.locations on a.locations_id equals b.id
join c in db.areas on b.id equals c.id
join d in db.categories on a.categories_id equals d.id
where a.title.Contains(searchQuery) && c.name.Equals(area)
select new {
a.id,
a.title,
a.description,
category = d.title
}).Take(10);
it doesn't show any error but it's not returning any data.
You have mistake in third line:
join c in db.areas on b.id equals c.id
should be
join c in db.areas on b.areas_id equals c.id

Convert special SQL query to Linq

do you know how write this SQL Query to linq ?
SELECT *
FROM
a
INNER JOIN b
ON a.FkSubmissionId = b.Id
RIGHT JOIN c
ON a.FkItemId = c.Id
WHERE
(b.FkUserId = '...' OR b.FkUserId is null)
and
(c.FkTenderId = 2)
I use Linquer and the best I have from the tool is that :
Linq :
from
items in _context.Items
from
si in _context.si
join s in _context.s
on new { fki = si.fki } equals new { fki = s.Id }
into
submissions_join
from
s in submissions_join.DefaultIfEmpty()
...
Result in SQL :
SELECT *
FROM
[Items] AS [t0]
CROSS JOIN [SubmissionsItems] AS [t1]
LEFT OUTER JOIN [Submissions] AS [t2]
ON [t1].[FkSubmissionId] = [t2].[Id]
WHERE
(([t2].[FkUserId] = #p0) OR (([t2].[FkUserId]) IS NULL))
AND
([t0].[FkTenderId] = #p1)
So the final result it not what I get from the query I need...
Thank you for your help !!!
Try this:
var part1 =
from x in a
join y in b on x.FkSubmissionId equals y.Id
where b.FkUserId = "..."
select new {x, y};
var part2 =
from c in z
where c.FkTenderId == 2
join xy in part1
on z.Id equals xy.x.FkItemId
into xys
from xy in xys.DefaultIfEmpty()
select new {xy.x, xy.y, z};
I would reorder your query so you can use a left join instead of a right join
var query = from c in context.C
from a in context.A.Where(x => c.Id == x.FkItemId)
.DefaultIfEmpty()
join b in context.B on a.FkSubmissionId equals b.id
where b.FkUserId == '...' || b.FkUserId == null
where c.FkTenderId == 2
select new {
a,
b,
c
};

Categories