LINQ query with multiple join result represented as comma seperated results - c#

The query below returns a list of leads joined to an "address" table, of where there can be multiple per lead.
I'm looking to return one response per lead, with addresses concatenated in the city view within the model and seperated by commas. If there are no cities in the join result, it should return '-'.
CURRENT OUTPUT
Company Name | Company City
===========================
Company 1 | Glasgow
Company 1 | London
Company 2 | London
Company 3 | NULL
DESIRED OUTPUT
===========================
Company 1 | Glasgow, London
Company 2 | London
Company 3 | -
QUERY
return (from t1 in db.Opportunities
from s1 in db.OpportunityStatus.Where(x => x.OpportunityStatus_ID == t1.StatusReason_ID)
from t2 in db.Leads.Where(x => x.Lead_ID == t1.Lead_ID)
from t3 in db.LeadAddresses.Where(x => x.Lead_ID == t2.Lead_ID).DefaultIfEmpty()
from t4 in db.Addresses.Where(x => x.Address_ID == t3.Address_ID).DefaultIfEmpty()
orderby (t1.Created) descending
select new FieldSalesPipelineViewModel
{
Id = t1.Opportunity_ID,
CompanyName = t2.Company_Name,
OpportunityTitle = t1.Opportunity_Title,
CompanyCity = "",
OpportunityStatusName = s1.OpportunityStatus_Name
}).Take(howMany);

Try a string-join:
CompanyCity = string.Join(",", (from p in db.Opportunities where t2.companyname == p.companyname select p.Companycity)
For your example:
return (from t1 in db.Opportunities
from s1 in db.OpportunityStatus.Where(x => x.OpportunityStatus_ID == t1.StatusReason_ID)
from t2 in db.Leads.Where(x => x.Lead_ID == t1.Lead_ID)
from t3 in db.LeadAddresses.Where(x => x.Lead_ID == t2.Lead_ID).DefaultIfEmpty()
orderby (t1.Created) descending
select new FieldSalesPipelineViewModel
{
Id = t1.Opportunity_ID,
CompanyName = t2.Company_Name,
OpportunityTitle = t1.Opportunity_Title,
CompanyCity = string.Join(",", (from t4 in db.Addresses Where t4.Address_ID == t3.Address_ID select t4.CompanyCity),
OpportunityStatusName = s1.OpportunityStatus_Name
}).Take(howMany);

Related

LINQ Query - Wrong Count Value

I am working with some SQL that has been provided and I am running into an issue where the count in the LINQ is different from the count in the SQL and would appreciate some help if possible.
The original SQL that was given is pretty poorly arranged and has a large number of nested queries. This being one of them. I have broken the query down into its main component and am now stitching it back together with LINQ.
The SQL that I am working with is here :
DECLARE #QSCollectionId UNIQUEIDENTIFIER = 'f52ec043-b360-4266-f95f-08d7c66074pe';
SELECT fieldid
Count(fieldid) AS fieldcount,
Sum(CASE
WHEN answer = [value] AND Answer IS NOT NULL THEN 1
ELSE 0
END) AS FieldAnswerMatchCount
FROM (SELECT DISTINCT FCI.fieldid,
answer,
QSA.qsrid,
FAG.fieldid AS dependentfield,
FAG.value
FROM forms.fieldconstraints FCI
INNER JOIN forms.sectionfieldmappings SFM
ON FCI.fieldid = SFM.fieldid
INNER JOIN forms.qssectionmappings QSSM
ON SFM.sectionid = QSSM.sectionid
INNER JOIN sessions.qsr
ON QSSM.qsid = qsr.qsid
--AND Qsr.QSCollectionId=#QSCollectionId
LEFT JOIN forms.answerguides FAG
ON
FCI.dependantanswerguideid = FAG.answerguideid
LEFT JOIN sessions.qsranswers QSA
ON FAG.fieldid = QSA.fieldid
AND Qsr.QsrId = QSA.qsrid
) AS
FieldConstr
GROUP BY fieldid
The LINQ
var id = Guid.Parse("f52ec043-b360-4266-f95f-08d7c66074be");
var firstResultPartThree = (from fci in FieldConstraints
join sfm in SectionFieldMappings on fci.FieldId equals sfm.FieldId
join qssm in QSSectionMappings on sfm.SectionId equals qssm.SectionId
join qsr in QSRs on new { qssm.QSId } equals new { qsr.QSId }
join ag in AnswerGuides on fci.DependantAnswerGuideId equals ag.AnswerGuideId into agResult
from agJoin in agResult.DefaultIfEmpty()
join qsrAnswers in QSRAnswers on new { agJoin.FieldId, qsr.QsrId } equals new {qsrAnswers.FieldId, qsrAnswers.QsrId} into qsrAnswersResult
from qsrAnswersJoin in qsrAnswersResult.DefaultIfEmpty()
//where qsr.QSCollectionId == id
select new {
FieldId = fci.FieldId,
Answer = qsrAnswersJoin.Answer,
QsrId = (Guid?)qsrAnswersJoin.QsrId,
DependentFieldId = agJoin.FieldId,
Value = agJoin.Value
}
);
firstResultPartThree.Dump();
var firstResultPartTwo = (from fr in firstResultPartThree
where fr.FieldId == Guid.Parse("98CA6B6F-4070-4CEB-E9F1-08D7C66278F9")
group fr by fr.FieldId into grp
select new {
FieldId = grp.Key,
Fieldcount = grp.Count(),
FieldAnswerMatchCount = grp.Count(x => (Guid?)grp.Key.Value != null)
}
);
The result of the LINQ in the example below gives me
FieldId | fieldcount | FieldAnswerMatchCount
98ca6b6f-4070-4ceb-e9f1-08d7c66278f9 | 4 | 4 |
The result of the sql for the same data is
98ca6b6f-4070-4ceb-e9f1-08d7c66278f9 | 3 | 2 |
The area that I am struggling with is
select new {
FieldId = grp.Key,
Fieldcount = grp.Count(),
FieldAnswerMatchCount = grp.Count(x => (Guid?)grp.Key.Value != null)
I understand that the count in the select is wrong, however I do not know how I need to correct it and would be grateful for some help.

Join data from multiple tables and group by Date and Id from another table using linq

I have these queries which retrieve results from multiple tables and want the expected result given below, Here is my code:
var q1 = (from sh in SessionHistories
where (System.DateTime.Now >= sh.FromDate && System.DateTime.Now <= sh.ToDate) && sh.IsDeleted == false
select sh
).ToList();
var FromDate = (from q in q1 select q.FromDate.Value).FirstOrDefault();
var ToDate = (from q in q1 select q.ToDate.Value).FirstOrDefault();
var allDates = (from idx in Enumerable.Range(0, (System.DateTime.Now - FromDate).Days)
select FromDate.AddDays(idx)).OrderBy(x => x.Date).ToList();
var q2 = (from ci in View_checkinout
where ci.EmployeeId == 2183
group ci by new { ci.CheckTime.Date } into g
select new
{
AttendanceDate = g.Key.Date,
EmployeeId = g.Select(x => x.EmployeeId).FirstOrDefault(),
CheckInTime = g.Select(x => new { x.CheckTime, x.CheckType }).Where(x => x.CheckType == "I").FirstOrDefault(),
CheckOutTime = g.Select(x => new { x.CheckTime, x.CheckType }).Where(x => x.CheckType == "O").OrderByDescending(x => x.CheckTime).FirstOrDefault()
})
.ToList();
var q3 = (from ad in allDates
join q in q2 on ad.Date equals q.AttendanceDate into outer
from o1 in outer.DefaultIfEmpty()
select new
{
o1,
ad
}).ToList();
and here is the expected result:
| EmployeeName | Designation | Late Arrivals| Short Leave| Half Leave| Full Leave| Cur. Month Total| Prev. Total|
|---------------|--------------|--------------|------------|------------|------------|------------|
| Name | Teacher| 0 | 0 |
| Name | Admin | 20 | 0 |
| Name | Peon | 0 | 30 |

Linq query join one table row to another table multiple row

Table name: Namelist
id | Name
------------
1 |xxxxx
2 |yyyyy
Table name: Category
id | Nameid |Categoryid
-----------------
1 |1 |5
2 |1 |4
3 |2 |3
4 |2 |8
I need a linq query result like this
id | Name |Categoryid
-----------------
1 |xxxx |5,4
2 |yyyy |3,8
I tried below linq but it displays first category id only
var list = from n in namelist
join c in category on n.id equals c.nameid
select new
{
n.id,
n.name,
c.categoryid
}
You can do this with Group Join and join all the category id's in the group with String.Join like this:-
var result = (from n in namelist
join c in categories
on n.Id equals c.NameId into g
select new
{
id = n.Id,
Name = n.Name,
CategorieIds = g.Select(x => x.CategoryId)
}).AsEnumerable()
.Select(x => new
{
Id = x.id,
Name = x.Name,
CategoryIds = String.Join(",",x.CategorieIds))
});
You can try String.Join:
var list = namelist
.Select(n => new {
n.id,
n.name,
categoryids = String.Join(",", category
.Where(c => c.nameid == n.id)
.Select(c => c.categoryid))
});
Use String.Join(). I modified your statement:
var list = from n in namelist
join c in category on n.id equals c.nameid
group g by new { n.id, n.name }
select new
{
id = g.Key.id,
Name = g.Key.name,
Categoryid = String.Join(",", g.Select(x => x.c.categoryid))
}
First you take a join on NameList and Category table and then bring them into objects using ToList or AsEnumerable methods like
var list = (from n in db.NameList
join c in db.Category on n.id equals c.nameid
select new
{
id = n.id,
Name = n.name,
Categoryid = c.id
}).ToList();
var list2 = from l in list
group by new {l.id, l.Name} into groupings
from g in groupings select new{
g.Key.id,
g.Key.Name,
CategoryId = string.Joing(",", groupings.Where(x=>x.NameId == g.Key.id).Select(y=>y.CategoryId))
};
The benefit of using ToList for fetching data from db is that you will only one query in database and all required records are fetched in the memory. The second statement will group those records by id and Name and will apply string.Join on CategoryId. Please note that if you use string.join method on Linq-to-Entities query, it will fail because this method cannot be converted into sql expression.

Converting SQL Join Query to Linq query

i want to join different column where the output would be this using linq
| Name | Address | Cellphone | Email |
| John | NY | n/a | johndoe#y.c |
| John | NY | 123456781 | n/a |
And i want my output to be one liner combined
| Name | Address | Cellphone | Email |
| John | NY | 123456781 | johndoe#y.c |
I Tried it on SQL server and this is the Query that answers the needed output
select a.ID, a.Name , a.Address ,(
SELECT wc1.[Values]
FROM Contact as wc1 where wc1.infoID = a.ID and wc1.ContactTypeID = 56) as Email
,(
SELECT wc1.[Values]
FROM Contact as wc1 where wc1.infoID = a.ID and wc1.ContactTypeID = 59) as Cellphone
from Info as a where a.ID = 100
Also tried it on Linq but it produces different row with same ID
var an = (from a in db.Info
join b in db.Contact on a.ID equals b.InfoID
where b.ContactTypeID == 56
|| b.ContactTypeID == 59
select new
{
a.ID,
a.LastName,
a.FirstName,
a.MiddleName,
b.ContactTypeID,
b.Values
}).ToList();
List<InfoList> wlist = new List<InfoList>();
foreach (var row in an)
{
InfoList ci = new InfoList
{
ID = row.ID,
Name = row.FirstName + " " + row.MiddleName + " " + row.LastName,
ContactType = GetLookupDisplayValById(row.ContactTypeID),
ContactValue = row.Values
};
wlist.Add(ci);
}
return Json(wlist.ToList(), JsonRequestBehavior.AllowGet);
Can someone help me translate this to a Linq Statement
Your SQL does not use JOIN, so why are you trying to introduce it in LINQ?
var an = (from a in db.Info
select new
{
a.ID,
a.LastName,
a.FirstName,
a.MiddleName,
Email = db.Contact.FirstOrDefault(b => b.InfoID == a.ID && b.ContactTypeIF == 56).Values,
Cellphone = db.Contact.FirstOrDefault(b => b.InfoID == a.ID && b.ContactTypeIF == 59).Values,
}).FirstOrDefault(x => x.ID == 100);
You can use the Pivot table the mentioned link shows how to use it: http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query

Linq to Sql Localisation query

Given the following tables I'd like to return the localised text for given culture or the text for the default culture where no row exist for the given culture.
diagram http://lh4.ggpht.com/_gjsCWAV_CZc/ShW6hC-eozI/AAAAAAAACbY/mXaBfiZtBY8/s400/diagram.png
So with the folowing data
Resources
ID Name
1 Donkey
2 Elephant
LocaleStrings
ID CultureID ResID LocaleText
1 1 1 Donkey
2 1 2 Elephant
3 2 1 baudet
I'd like to be able to return the following for the French culture
baudet
elephant
I've tried various queries based around LEFT JOINS samples I've seen but I'm stuck.
var ct = from r in db.Resources
join lt in db.LocaleStrings
on r.ID equals lt.ResID into res
from x in res.DefaultIfEmpty()
select new
{
CultureID = x.CultureID,
LocaleText = x.LocaleText,
ResID = x.ResID
};
var text =
from c in db.Cultures
join t in ct
on c.ID equals t.CultureID into cults
from x in cults.DefaultIfEmpty()
select x;
I'm sure there's a better way, but this seems to work:
var ct =
from c in db.Cultures
from l in db.LocaleStrings
from r in db.Resources
where r.ID == l.ResID
select new
{
CultureID = c.ID,
LocaleText = l.CultureID == c.ID ? l.LocaleText : r.Name,
ResID = r.ID,
LSID = l.CultureID == c.ID ? l.ID : 0
};
var text =
from t in ct
where t.LSID != 0 || (t.LSID == 0 && !((from ac2 in ct
where ac2.LSID > 0 && ac2.CultureID == t.CultureID
select ac2.ResID).Contains(t.ResID)))
select new
{
CultureID = t.CultureID,
LocaleText = t.LocaleText,
ResID = t.ResID
};

Categories