简体   繁体   English

如何使用LINQ和实体框架6进行表联接?

[英]How do I do a table join using LINQ and entity framework 6?

I have three tables: Exam > Objectives > ObjectiveDetails 我有三个表:考试>目标> 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: 或像这样从ObjectiveDetails:

 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? 我应该从db.Exams开始还是应该从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. 但是对于LINQ,我不确定从哪里开始。

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;

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. 显式使用Linq的'join'关键字没有任何问题,但如果EF知道实体之间的关系,通常就没有必要。

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

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 这具有与先前相同的行为,但是使用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 最后,我们可以将列表转换为json结果

return Json(geracoes, JsonRequestBehavior.AllowGet);

note that with the "select new" we create an new type of object, with only two properties 请注意,通过“选择新”,我们创建了一种只有两种属性的新型对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM