I have 2 tables:
Metrics
(id, Metric) :[{1,Metric1},{2,Metric2},{3,Metric3}]
id | Metric
------------------------------------------------------------
1 | Metric1
2 | Metric2
3 | Metric3
MetricsValuePerPerson
(id, PersonId, Metricid, Value)
id | PersonId | Metricid | Value
------------------------------------------------------------
1 | 1 | 1 | P1metric1Value
2 | 1 | 2 | P1Metric2Value
3 | 1 | 3 | P1metric3Value
4 | 2 | 1 | P2Metric1Value
5 | 2 | 2 | P2metric2Value
6 | 2 | 3 | P2Metric3Value
I want to show the values in a grid where each row is a Person
and each column is a Metric
:
PersonId | Metric1 | Metric2 | Metric3
------------------------------------------------------------
P1 | P1metric1Value | P1Metric2Value | P1Metric3Value
P2 | P2metric1Value | P2Metric2Value | P2Metric3Value
Here is how I try to load the store:
var metricValues = from mv in dc.MetricsValuePerPerson
join m in dc.Metrics on mv.Metricid equals m.id
select new { Personid = mv.Personid, Metric1 = (codesnippet) , Metric2 = (codesnippet), Metric3 = (codesnippet) };
How can I replace (codesnippet)
to get the Value
of Metricx
?
In LINQ, provided you have established relations in the database, you very rarely need to use JOIN keyword. In your case, within the DB you have relation between MetricsValuesPerPerson and Metrics, right? If so then:
var metricValues = from mv in dc.MetricsValuePerPerson
select new {
Personid = mv.Personid,
Metric1 = mv.Metric.Metric };
The result doesn't seem to be meaningful though (probably you would want to add Value too).
EDIT: This would be like a pivot, assuming you only have 3 metrics and at most 1 from each type of metric per person (ie: there is no personId, metricId, value like (1,1,10) and (1,1,20).
var result = from mv in MetricsValuePerPersons.Where(mvpp => mvpp.Metricid == 1)
let mv2 = MetricsValuePerPersons.SingleOrDefault(mvpp => mvpp.PersonId == mv.PersonId && mvpp.Metricid == 2)
let mv3 = MetricsValuePerPersons.SingleOrDefault(mvpp => mvpp.PersonId == mv.PersonId && mvpp.Metricid == 3)
select new {
PersonId = mv.PersonId,
Metric1 = mv.Value,
Metric2 = mv2.Value,
Metric3 = mv3.Value,
};
You can do this by using GroupJoin
(equivalent to LEFT JOIN
in SQL). Join the MetricsValuePerPerson
with Metrics
and then GroupBy
by the PersonId
then Select
the result. The sample code is in Lambda Join
, but you can convert this to LINQ
.
Working sample : C# Fiddle
var result = metricValuePerPerson.GroupJoin(metrics, mv => new { Id = mv.PersonId }, m => new { Id = m.Id },
(mv, m) => new { mv = mv, m = m })
.SelectMany(x => x.m.DefaultIfEmpty(), (x, y) => new {mv = x.mv, m = y })
.GroupBy(g => g.mv.PersonId)
.Select(x =>
{
var grouped = x.ToList();
return new
{
PersonId = x.Key, //The below are sample code, please use your actual code.
Metric1 = grouped[0].mv.PersonId + "|" + grouped[0].m.Metric + "|" + grouped[0].mv.Value,
Metric2 = grouped[1].mv.PersonId + "|" + grouped[1].m.Metric + "|" + grouped[1].mv.Value,
Metric3 = grouped[2].mv.PersonId + "|" + grouped[2].m.Metric + "|" + grouped[2].mv.Value,
};
})
.ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.