I've got the following code:
var preGroup =
from l in e.WorkOrderRequests
join w in e.WorkOrders on l.WorkOrderRequestKey equals w.WorkOrderRequestKey into lw
from l2 in lw.DefaultIfEmpty()
select new { l.WorkOrderRequestStatusKey,
l.WorkOrderRequest_Status.Status,
w.Property.Address.StateKey,
w.Property.Address.MetroKey };
The relationship structure is that a Work Order Request can have many Work Orders, so it is a 1 to many relationship. I want to do a select so that each work order request will show up for as many times as there are work orders attached to it. But also it still should appear if there are no work orders attached. So a left outer join makes sense. The select above doesn't work, but that shows the data that I want to select. I need to then group this data:
var workOrderRequests =
(from l in preGroup.ToList()
group l by new { l.WorkOrderRequestStatusKey, l.Status, l.StateKey, l.MetroKey } into g
select new DashboardView
{
StatusKey = g.Key.WorkOrderRequestStatusKey,
StatusName = g.Key.Status,
StateKey = g.Key.StateKey,
MetroKey = g.Key.MetroKey,
Count = g.Count()
});
I can't get to the grouping because my preGroup query is not working. I have been able to accomplish this for other things, but those are all 1 to 1 relationships. Any help is much appreciated.
Related
I have a VacancyApply table and that table consist of Status Id's,So i need Top5 data from each Status.I want to get top 5 records of each status.Status is int like 1,2,3
My Query
var result = (from ui in _context.VacancyApply
join s in _context.UserProfile on ui.UserId equals s.UserId
join x in _context.Vacancy on ui.VacancyId equals x.VacancyId
join st in _context.Status on ui.StatusId equals st.StatusId
where ui.UserId == userId && ui.IsActive == true
orderby ui.StatusId
select new VacancyApply
{
VacancyApplyId = ui.VacancyApplyId,
VacancyId = ui.VacancyId,
UserId = ui.UserId,
StatusId = ui.StatusId,
VacancyName = x.VacancyName,
VacancyStack = x.VacancyStack,
VacancyEndDate = x.VacancyEndDate,
StatusName = st.StatusName,
UserName = s.FirstName
}).ToList();
Now what I can see from the output is that it contains One VacancyId and One VendorId.
I have a feeling that you have Many to Many relationships between Vacancy and Status tables.
But nevertheless, the answer is very simple: you need to use LINQ Take extension method (maybe it will be good to make it follow after the OrderBy because just taking the last items doesn't make sense without some logic):
var output = (logic to join, filter, etc.).OrderBy(lambda).Take(N); // N is the number of
// items you want to select
Now if you want Generally to take the last items from Vacancy and only after join it with Status do this:
var output = Vacancy.OrderBy(lambda).Take(N).(now join, filter, etc. with other tables);
However, if you want to Group all similar Statuses in conjunction with Vacancies and only after taking the Top items, use GroupBy:
var output = (logic to join, filter, etc.).GroupBy(st => st.StausId).
.Select(group => group.OrderBy(lambda).Take(N));
I have three sets of data representing a counted value, grouped by country code.
select distinct m.CountryCode, count(m.MetricId) as 'Impressions'
from Metrics m
inner join impressions i on m.MetricId = i.MetricId
where ...
group by m.CountryCode
select distinct m.CountryCode, count(m.MetricId) as 'Conversions'
from Metrics m
inner join Conversions c on m.MetricId = c.MetricId
where ...
group by m.CountryCode
..and there's a third one that joins with a table called "Leads"
So each of these give me a nice set of distinct country codes and a corresponding number.
CountryCode Impressions
AU 25
DE 34
US 264
CountryCode Conversions
AU 11
US 140
something like that. so my goal is to get all three recordsets merged to one that looks like this:
CountryCode Impressions Conversions Leads
US 264 140 98
I'd like to learn how to do this with LINQ and without doing three queries. There's gotta be a more straightforward approach but I've been working on it too long and my eyes aren't seeing it. Would appreciate a nudge in the proper direction, thanks
var qry1 = (from m in Db.Metrics
join i in Db.Impressions on m.MetricId equals i.MetricId
//where
group m by m.CountryCode into grp
select new
{
CountryCode = grp.Key,
Impressions = grp.Count()
});
var qry2 = (from m in Db.Metrics
join c in Db.Conversions on m.MetricId equals c.MetricId
//where
group m by m.CountryCode into grp
select new
{
CountryCode = grp.Key,
Conversions = grp.Count()
});
var result = (from x in qry1
join y in qry2 on x.CountryCode equals y.CountryCode
select new
{
CountryCode = x.CountryCode,
Impressions = x.Impressions,
Conversions = y.Conversions
});
var lst = result.ToList();
The first 2 queries are lazy, they will not yet execute. The result-variable just joins them together and the last part executes the final query and materializes the objects.
Splitting these in their separate queries can be helpfull in keeping it simpler.
When I need to join some tables using linq, and when those tables consist of a lot of fields, it takes a lot of work to get all the data that I need. For instance:
var result = from i in Person
join y in Works
on i.PID euqals y.PID
join z in Groups
on y.GID on z.GID
select new {Name = i.Name, Work = y.work, WG = z.GroupName};
How can make the query return all the tables ?
I guess what you need is simply this :
var Query = from x in Table_1
join y in Table_2
on x.id equals y.id
where x.Country.Equals("X Country")
select new {x,y};
There are four tables:
Questions(questionId, question)
QuestionTags(questionTagId, questionId, tagId)
CodingKeys(codingKeyId, codingTypeId ..)
Codings(codingId, codingKeyId, coding ..)
I want to select all question tagIds and their codings (codingKeyId is foreign key of tagId) that are represented in Questions... So if I have 10 different codings in Codings table but only two of them are represented in Questions I want to select only these two.
I tried with join like this:
var query = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
select new
{
tagId = qt.tagId,
coding = c.coding
};
But the above solution gave me double results. For example, if one tag is included in more than one question, I get the same tag twice (I tried distinct, but that didn't work).
I also tried using Any:
var query= context.QuestionTags
.Where(qt => qt.Questions.QuestionTags.Any(q => q.tagId == qt.tagId))
.Select(qt => new
{
codingKeyId = qt.questionId,
coding = context.Codings.FirstOrDefault(c => c.CodingKeys.codingKeyId == qt.tagId).coding
});
The same thing happened here, I got duplicate results, but Distinct didn't work (don't know why).
However, if I use this SQL statement:
SELECT distinct tagId, coding
FROM QuestionTags
LEFT OUTER JOIN Codings ON codingKeyId LIKE QuestionTags.tagId
WHERE Codings.languageId = 1
I get the right result, but I don't want to write and store a procedure for this. I really wan't to know if I can solve this with EF (linq), and I am also not sure if distinct is the right solution.
Thanks for your help.
You can use group by in order to get just the results you want.
var query = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
group qt by new {tagId = qt.tagId,coding = c.coding } into element
select new
{
tagId = element.Key.tagId,
coding = element.Key.coding
};
Please mark it as answer if you find it useful
var result = from qt in context.QuestionTags
join c in context.Codings on qt.tagId equals c.codingKeyId
where c.languageId == 1
select new
{
codingKeyId = qt.tagId,
coding = c.coding
};
return result.Distinct()
Ok, like this it is working, but is this the only way to use it with distinct and join... I am not sure if this is the right solution (but it gives me the right result) ... maybe it can be optimized a bit...
Try
var query = from qt in context.Codings
join c in context.QuestionTags on qt.tagId equals c.codingKeyId
select new
{
tagId = qt.tagId,
coding = c.coding
};
I have 2 tables within my EF4 project. They dont have a join.
CustomerTable
CustomerId
ConsumerName
AllowEmails
PurchaseTable
PurchaseId
CustomerId
PurchaseDate
......
What I am trying to do is return a grouped Customer when they have transactions within the PurchaseTable. If they haven't made any purchases or consumer Id isn't yet added to the CustomerId I want to ignore them.
I have a linq query that is working like I want
var query = from t in ctx.PurchaseTable
join j in ctx.CustomerTable on t.CustomerId equals
j.ConsumerId
where j.AllowEmails==true
group t by new
{
t.CustomerId,
j.ConsumerName,
j.EmailAddress
}
into g
select new {Customer = g.Key};
Now I could just do a foreach loop and add the results into a list however I think it would be nice to add to the list as part of the query.
This is what I have got so far.
var data = (from t in ctx.PurchaseTable
join j in ctx.CustomerTable on t.CustomerId equals
j.CustomerId
where j.AllowEmails== true
//group t by new //group t by new ConsumerModel
group t by new CustomerModel
{
CustomerName= t.CustomerName,
Email= j.EmailAddress,
CustomerId = j.CustomerId
}
into g select g);
Can anyone point me in the right direction to fix my query?
Thanks for your help!
You need to select g.Key.
g is an IGrouping<CustomerModel, Purchase> that includes the elements in the group.