c# - 使用 Include() 和条件过滤器连接两个表

标签 c# sql linq entity-framework-6

我有现有代码要更新。我想加入另一个名为 Table3 的表。 由于查询对 Table2 有一个 include,我想添加另一个带有条件过滤器的 .Include 并避免左连接。

当我将 .include 添加到 .where 时,我无法访问 t3Id。 Intellisense 仅显示表 Table3 而不是 Id 字段。

我错过了语法吗?谢谢。

Table1 有一个名为 t1Id 的键。

 var query = (from e in ctx.Table1
    .Include(r => r.Table2.Select(p => p.name))
    .Include(rj => rj.Table3).Where(s => s.t1Id == t3Id)
    select e).ToList();

Table1 将具有以下内容:

Id  name  
1   Joe   
2   Mary
3   Harry

Table3 将具有以下内容:

t1Id   title
3      staff
3      fulltime

预期结果:

1  Joe
2  Mary
3  Harry  [{2, staff}, {3, fulltime}]

由于 Harry 在映射表中有一条记录,他将有一个包含 Table3 行的数组。

最佳答案

最好尽可能使用Select 而不是IncludeSelect 将允许您仅查询您真正计划使用的属性,从而使选定数据从数据库管理系统传输到您的进程的速度更快。

例如,如果您查询“Schools with their Students”,Student 将有一个外键,其值等于 School 的主键。因此,如果您有 School 10,现在所有 5000 名学生都将拥有一个值为 10 的 SchoolId。将同一个值 10 发送超过 5000 次有点浪费。

When querying data, always use Select. Only use Include if you plan to update the fetched data.

您的查询(在方法语法中):

var result = dbContext.Table1
    .Where(table1Element => ...)    // only if you don't want all elements of Table1 
    .Select(table1Element => new
    {
         // only select the table1 elements that you plan to use:
         Id = table1Element.Id,
         Name = table1Element.Name,

         // Select the items that you want from Table 2:
         Table2Items = table1Element.Table2
                       .Where(table2Element => ...) // only if you don't want all table2 elements
                       .Select(table2Element => new
                       {
                            // Select only the properties of table2 you plan to use:
                            Id = table2Element.Id,
                            Name = table2Element.Name,
                            ...

                            // the following not needed, you already know the value:
                            // Table1Id = table2Element.table1Id, // foreign key
                       })
                       .ToList(),

         // Table3: your new code:
         Table3Items = table1Element.Table3
                       .Select(table3Element => new
                       {
                            // again: only the properties you plan to use
                            Id = table3Element.Id,
                            ...

                            // the following not needed, you already know the value:
                            // Table1Id = table3Element.table1Id, // foreign key
                       })
                       .ToList(),
    });

您看到读者更容易看出他获得了哪些属性吗?如果其中一个表被展开,那么新属性就不会在此查询中获取,毕竟:用户显然不需要新属性。它们也没有在此功能的规范中描述。

注意:因为我使用了 new,所以我的类型是匿名类型。您只能在您的函数中使用它们。如果需要返回获取的数据,将数据放在一个已知的类中:

.Select(table1Element => new Table1Class()
{
    Id = table1Element.Id,
    Name = table1Element.Name,
    ...
});

再一次:考虑不要填写外键,因为您可能不会使用它们

关于c# - 使用 Include() 和条件过滤器连接两个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57397912/

相关文章:

.net - 查找 LINQ 提供程序支持的方法

c# - 在没有内存泄漏的情况下清除 ListView 项

c# - 如何在 C# 中访问 Dictionary<TKey, TValue>.Item 属性

c# - 全局异常捕获仅在调试 WinForms 应用程序时有效

sql - 等待数据库引擎恢复句柄失败。检查 SQL Server 错误日志以了解潜在原因

c# - LINQ Select() 或 ForEach 循环

c# - 使用 C++/CLI 作为 'middleware' 使用 native C++ 中的 .NET 类

mysql - mysql查询中独立列的分组

c++ - 为什么 sqlite 的删除总是成功,即使要删除的行不存在?

c# - 如何计算分组后的加权平均价格?