У меня три таблицы: Экзамен> Цели> ObjectiveDetails
Вот как они выглядят:
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; }
}
Должен ли я начать с экзамена следующим образом:
var result = await db.Exams
.Where(e => e.Name == name)
или из ObjectiveDetails:
var result = db.ObjectiveDetails .. ??
Как я могу получить объект, который показывает цели и объективные данные для данного экзамена? Должен ли я начинать с db.Exams или мне нужно начинать с db.ObjectiveDetails? Все, что мне нужно, это сделать соединение (если только в реляционном мире). Но с LINQ я не уверен, с чего начать.
Это то, что я обычно делаю, когда речь идет о присоединении к двум или более таблицам, не знаю, что именно вы ищете:
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;
Предполагая, что Entity Framework правильно связала отношения между вашими объектами, следующее должно вернуть один экзамен вместе с связанными целями и деталями: -
var query = db.Exams.Include(e => e.Objectives.Select(o => o.ObjectiveDetails));
var examEntity = query.SingleOrDefault(e => e.ExamId == targetExamId);
Вышеприведенный запрос будет использовать внешние соединения за кулисами, поэтому Экзамен всегда будет возвращен (если найден), даже если нет связанных Целей/Подробности. Экзамен возвращается как единый объект с дочерними Целями, включенными, если применимо.
В качестве альтернативы, следующий результат возвращает сплющенный результирующий набор, используя внутренние соединения: -
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();
Нет ничего плохого в использовании ключевого слова Linq "join" явно, но обычно это не нужно, если EF знает, как связаны сущности.
это возвращает перечисление сгруппированного выбора, ключевого плюс счетчика. в конце конвертируется в список, так что может получить все данные в этот момент
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();
это имеет такое же поведение предыдущего, но два способа получить одну и ту же информацию с 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();
в конце мы можем преобразовать список в json-результат
return Json(geracoes, JsonRequestBehavior.AllowGet);
обратите внимание, что с помощью "select new" мы создаем новый тип объекта с двумя свойствами
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
join
должны использовать equals
вместо =
. Это должно быть join o in objective on e.objectiveid equals o.id
, то же самое для другого соединения.