实体框架加入3个表

Erç*_*ğlu 116 c# entity-framework entity-framework-4 entity-framework-4.1 entity-framework-5

我想加入三张桌子,但我无法理解这个方法......

我完成了加入2个表

        var entryPoint = dbContext.tbl_EntryPoint
            .Join(dbContext.tbl_Entry,
                c => c.EID,
                cm => cm.EID,
                (c, cm) => new
                {
                    UID = cm.OwnerUID,
                    TID = cm.TID,
                    EID = c.EID,
                }).
            Where(a => a.UID == user.UID).Take(10);
Run Code Online (Sandbox Code Playgroud)

表

我想在TID PK中包含tbl_Title表并获取Title字段.

非常感谢

Mar*_*zek 184

我认为使用基于语法的查询会更容易:

var entryPoint = (from ep in dbContext.tbl_EntryPoint
                 join e in dbContext.tbl_Entry on ep.EID equals e.EID
                 join t in dbContext.tbl_Title on e.TID equals t.TID
                 where e.OwnerID == user.UID
                 select new {
                     UID = e.OwnerID,
                     TID = e.TID,
                     Title = t.Title,
                     EID = e.EID
                 }).Take(10);
Run Code Online (Sandbox Code Playgroud)

你应该添加orderby子句,以确保Top(10)返回正确的前十项.

  • 非常感谢您的方法;工作清晰,但我想按我的要求查看答案,再次感谢。 (2认同)
  • 我更喜欢其他语法,除非涉及连接……其他语法要复杂得多。我根本不明白。 (2认同)

Pyn*_*ynt 71

这是未经测试的,但我相信语法应该适用于lambda查询.当您使用此语法连接更多表时,您必须深入查看新对象以获得要操作的值.

var fullEntries = dbContext.tbl_EntryPoint
    .Join(
        dbContext.tbl_Entry,
        entryPoint => entryPoint.EID,
        entry => entry.EID,
        (entryPoint, entry) => new { entryPoint, entry }
    )
    .Join(
        dbContext.tbl_Title,
        combinedEntry => combinedEntry.entry.TID,
        title => title.TID,
        (combinedEntry, title) => new 
        {
            UID = combinedEntry.entry.OwnerUID,
            TID = combinedEntry.entry.TID,
            EID = combinedEntry.entryPoint.EID,
            Title = title.Title
        }
    )
    .Where(fullEntry => fullEntry.UID == user.UID)
    .Take(10);
Run Code Online (Sandbox Code Playgroud)

  • 那太可怕了.如果我在生产代码中发现了这样的查询,我会立即重构它.尽管如此,仍然可以+1来回答问题! (11认同)
  • @Dan出于好奇,它只是在c,cm和ccm的所有命名约定中没有想到,或者只是使用linq和lambda来执行连接所需的语法是可怕的?如果是前者,并且您想编辑帖子以获得更好的布局,请务必使用它.我仍然是实体框架的新手,并且仍在浸泡最佳实践,所以如果你有建议让这个答案对未来的用户更有说服力,我会很感激你的帮助. (6认同)
  • 当我评论时,我没有充分考虑到确切的原因,但肯定命名约定会损害可读性(从OP复制而来).此外,作为行的开头的逗号会严重损害可读性(对我而言是主观的),并且空格/缩进可能会略微改善.自从您提出要求后,我已经提交了所有这些(恕我直言)改进的编辑. (4认同)
  • 我只是没有得到反对逗号起始行的参数.我是一个坚定的信徒,因为它使评论个别条款/论据真的很容易.它看起来更漂亮:-) (4认同)
  • 代码格式化通常是有偏见的,但是大多数人都同意的一般事情看起来更好.至于命名约定,我以前称之为真正的短名称,但我现在可以足够快地打字(甚至不考虑像Intellisense这样的东西)保存的少数字符不值得在可读性方面造成损害而不是详细命名事物,例如"EntryID"与"EID","combinedEntry"对比"cm"等等.最终,其他人将会阅读我的代码,而我宁愿他们也不会因为我的行数线性函数而对我产生仇恨.他们必须阅读/维护的代码. (2认同)
  • 除了可读性和语义之外,我认为这比通常的“来自context.table join ...中的x”更好的答案。这样,您可以动态构建Joins和Where子句,并在以后添加分页和填充。 (2认同)
  • 很好的答案,谢谢。需要注意的一点是,如果您的查询包含包含内容,那么这些内容必须放在连接之前。 (2认同)