Reputation:
I have three tables: Exam > Objectives > ObjectiveDetails
Here's what they look like:
public class Exam
{
public Exam()
{
this.Objectives = new HashSet<Objective>();
}
public int ExamId { get; set; }
public int SubjectId { get; set; }
public virtual ICollection<Objective> Objectives { get; set; }
}
public class Objective : AuditableTable
{
public Objective()
{
this.ObjectiveDetails = new HashSet<ObjectiveDetail>();
}
public int ObjectiveId { get; set; }
public int ExamId { get; set; }
public int Number { get; set; }
public virtual Exam Exam { get; set; }
public virtual ICollection<ObjectiveDetail> ObjectiveDetails { get; set; }
}
public partial class ObjectiveDetail
{
public int ObjectiveDetailId { get; set; }
public int ObjectiveId { get; set; }
public int Number { get; set; }
public string Text { get; set; }
public virtual Objective Objective { get; set; }
}
Should I start from exam like this:
var result = await db.Exams
.Where(e => e.Name == name)
or from ObjectiveDetails like this:
var result = db.ObjectiveDetails .. ??
How can I get an object that shows the objectives and objective details for a given exam ? Should I start with db.Exams or should I start with db.ObjectiveDetails? All I need is to do a join (if in the relational only world). But with LINQ I am not sure where to start.
Upvotes: 2
Views: 10777
Reputation: 3676
This is what i normally do when it comes to joining two or more tables, don't know if that's what you are looking for :
var info = from p in db.Exam
join q in db.objective on p.objectiveid equals q.id
join r in db.objectivedetails on q.objectivedeailsId equals r.id
select new
{
ExamId = p.ExamId
SubjectId= p.SubjectId
ObjectiveId= q.ObjectiveId
Number = q.Number
ObjectiveDetailId = r.ObjectiveDetailId
Text = r.Text
} into x
select x;
Upvotes: 8
Reputation: 1756
Assuming Entity Framework has wired up the relationships between your entities correctly, the following should return a single exam, together with associated Objectives and Details:-
var query = db.Exams.Include(e => e.Objectives.Select(o => o.ObjectiveDetails));
var examEntity = query.SingleOrDefault(e => e.ExamId == targetExamId);
The above query will use outer joins behind the scenes, so an Exam will always be returned (if found), even if there are no associated Objectives/Details. The Exam is returned as a single object with child Objectives included if applicable.
Alternatively, the following will return a flattened result set using inner joins:-
var query = from exam in db.Exams
from objective in exam.Objectives
from detail in objective.ObjectiveDetails
select new
{
ExamId = exam.ExamId,
SubjectId = exam.SubjectId
ObjectiveId = objective.ObjectiveId
ObjectiveNumber = objective.Number
DetailId = detail.DetailId
DetailNumber = detail.Number
Text = detail.Text
};
var examDetails = query.Where(e => e.ExamId == targetExamId).ToArray();
There's nothing wrong with using Linq's 'join' keyword explicitly, but it's generally unnecessary if EF knows how entities are related.
Upvotes: 1
Reputation: 127
this returns a enumeration of a grouped select, key plus count. at the end converts to list, so that can retrieve all the data at that moment
var results = simulacao.Geracao
.SelectMany(g => g.ObterCarteiras())
.SelectMany(cg => cg.CarteiraGeneticaInvestimento)
.SelectMany(cgi => cgi.HistoricoNaoPodeInvestir)
.GroupBy(hnpi => hnpi.TipoNaoPodeInvestir)
.Select(g => new { Tag = g.Key, Frequency = g.Count() })
.ToList();
this has the same behavior of the previous, but two ways of getting de same info with LINQ
var geracoes = (from g in simulacao.Geracao
from cg in g.ObterCarteiras()
from cgi in cg.CarteiraGeneticaInvestimento
from hnpi in cgi.HistoricoNaoPodeInvestir
group hnpi by hnpi.TipoNaoPodeInvestir into g
select new
{
TipoNaoPodeInvestir = Utilities.GetEnumDescription((EnumTipoNaoPodeInvestir)g.Key),
Count = g.Count()
}).ToList();
at the end we can convert the list to a json result
return Json(geracoes, JsonRequestBehavior.AllowGet);
note that with the "select new" we create an new type of object, with only two properties
Upvotes: 0
Reputation: 256
From e in db.Exam
join o in objective on e.objectiveid = o.id
join od in objectivedetails on o.objectivedeailsId = od.id
select e
Upvotes: -2