【问题标题】:LINQ using multiple .join extensions with multiple (4) or more tablesLINQ 使用具有多个 (4) 或更多表的多个 .join 扩展
【发布时间】:2017-05-10 21:00:51
【问题描述】:

我在使用我的数据库中的多个 (4) 表来设置 LINQ 查询时遇到问题。我可以使用我正在学习的 LINQ 语法毫无问题地连接两个表,但不仅如此,还给我带来了麻烦。我正在尝试将下面的 SQL 查询转换为 LINQ 格式。

select count(distinct applicant)
from apps inner join
     stu_terms on applicant = student_id inner join
     acad_prog on apps_program = acad_program and st_acad_lvl = acad_lvl inner join
     application_statuses on apps_status = application_status
where st_active_cred >= 0 and apps_start_term = @term and
      apps_admit_status = @status and apps_stu_type = @type and
      application_code is not null

我不熟悉 LINQ 查询以及所有内容如何组合在一起,但这就是我想出的。这有点棘手,因为除了有 4 个表之外,where 子句从三个不同的表中提取,而我设置它的方式迫使我在查询中分散 .Where() 方法。见下文:

int num = db.apps.Distinct()
            .Join(db.application_statuses,
            a => a.apps_status,
            aa => aa.application_status,
            (a, aa) => new { apps = a, application_statuses = aa })
            .Where(j => j.apps.admit_status == status && j.apps.apps_stu_type == type && j.apps.apps_start_term == term && j.application_statuses.application_code != null)
                .Join(db.stu_terms,
                a => a.apps.applicant,
                st => st.student_id,
                (a, st) => new { apps = a, stu_terms = st })
                .Where(j => j.stu_terms.st_active_cred >= 0)
                    .Join(db.acad_prog,
                    a => a.apps.apps.apps_program,
                    ap => ap.acad_program,
                    (a, ap) => new { apps = a, acad_prog = ap })
                        .Join(db.stu_terms,
                        ap => ap.acad_prog.acad_lvl,
                        st => st.st_acad_lvl,
                        (ap, st) => new { acad_prog = ap, stu_terms = st }).Count();  

如您所见,Where 方法位于两个不同的位置,因为它只能在这些位置查看特定表中的列。我看到的大多数问题是因为我不知道我是否正确地将这四个表连接在一起。大多数这些东西对我来说仍然是新的(Distinct() 方法的随机放置表明)

感谢您的帮助。

【问题讨论】:

  • 如果您的查询如此复杂,请不要使用 linQ
  • 这是什么? Linq2SQL 还是 EntityFramework?你的模型中有任何关系吗?
  • @fhogberg 这是实体框架。我不这么认为。这些表的列包含相似的数据,但彼此之间不是 FK。
  • 这确实不是适合这项工作的工具。如果你不能改变模型。坚持使用 SQL。如果您的所有模型都像这样,请一起摆脱 EF 并改用 SqlCommand 。 EF只会给你带来痛苦。
  • @fhogberg 我开始意识到这一点。谢谢。

标签: c# sql-server asp.net-mvc linq join


【解决方案1】:

LINQ 已经在您的域模型中包含连接(如果您使用 Code-First,请记住 ICollection)

因此您无需指定连接。它默认使用延迟加载,这意味着在您使用它们时会自动创建连接(= call .ToList() )。

例如。

db.Apps.Where(el => el.Students.Any(dl => dl.Type == 'Something')).ToList()

如果您想要更快的性能,您可以使用带有 Include 的预加载。从一开始就创建连接。

db.Apps.Include(el => el.Students.Select(dl => dl.childOfStudents)) 

因为你是新人。您还应该知道,系统会跟踪所有查询的更改,这会降低性能。

因此,如果您不需要更改+更新对象,请使用 .AsNonQueryable() 以获得更好的性能。

PS。你仍然可以使用 SQL --> https://msdn.microsoft.com/en-us/library/jj592907(v=vs.113).aspx :)

【讨论】:

  • 我正在使用的数据库的设置方式,我认为仅使用原始 SQL 查询会为我省去很多麻烦。感谢您的帮助。
【解决方案2】:

非常很少在 LINQ 中将 Join() 与数据库一起使用。相反,您只需导航导航属性。使用合适的模型,这很简单:

      var q = from a in apps
              where a.StuTerms.ActtiveCredits > 0
                 && a.StartTerm = startTerm
                 && a.ApplicationStatus.AdmitStatus = admitStatus
                 && a.StudentType = studentType
                 && a.application_code != null
              select a;

     var applicants = q.GroupBy(a => a.ApplicantId).Count();

大卫

【讨论】:

  • 看到上面 OP 的评论,这似乎是极少数情况之一。但也许,作为替代方案,您可以证明查询语法无论如何都更容易,也可以使用连接。顺便说一句,您的查询中没有 select
  • “这似乎是罕见的情况之一”我不这么认为。您不需要数据库中的真正 FK 来在 EF 模型中声明导航属性和外键列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多