【问题标题】:Combine multiple datatables into single result in ASP.Net Core在 ASP.Net Core 中将多个数据表组合成单个结果
【发布时间】:2021-04-12 18:07:52
【问题描述】:

我有四个表在上下文中传递给页面。 4 个表中的每一个都由一个 Id 列连接。我想显示一个带有表格的页面,该表格结合了 4 个表格中的每一个表格的列。我还想对数据进行排序或搜索,并根据 1 个或所有表显示结果(例如,如果表 2 包含“名称”列,则搜索结果应仅显示与该名称匹配的行)

   public IList<AllTables> AllTableData {get;set;}

   public async Task OnGetAsync(
       string sortOrder,
       string queryFilter,
       string searchString)
   {
   //setting sort and search Params
   //......

   IQueryable<Table1> table1= _context.Table1.Select(f => f);
   IQueryable<Table2> table2= _context.Table2.Select(f => f);
   IQueryable<Table3> table3= _context.Table3.Select(f => f);
   IQueryable<Table4> table4= _context.Table4.Select(f => f);

   if (!String.IsNullOrEmpty(searchString))
   {
      // e.g. table1= table1.Where(s => s.Id.ToString() == searchString);
    }

    //Example for sorting
    switch (sortOrder)
    {
        case "Id":
           table1= table1.OrderBy(s => s.Id);
           break;
        case "Name":
           table2= table2.OrderBy(s => s.Id);
           break;
    }

    //How do I combine all four tables
    AllTableData = await (Join Tables 1-4).AsNoTracking().ToListAsync();
    }

我尝试创建一个新类,如下所示

  public Class AllTables
  {
     public Table1 Table1{get;set;}
     public Table2 Table2{get;set;}
     public Table3 Table3{get;set;}
     public Table4 Table4{get;set;}
  }

然后像这样组合数据

  AllTableData= await table1
            .Select(f=>new AllTables(
                f,
                table2.Where(g => g.Id== f.Id).FirstOrDefault(),
                table3.Where(h => h.Id== f.Id).FirstOrDefault(),
                table4.Where(i => i.Id== f.Id).FirstOrDefault(),
                )).AsNoTracking().ToListAsync();

这给了我完整的表格数据,但是当我尝试根据 table2.Name 进行排序时,排序不起作用。

【问题讨论】:

    标签: asp.net asp.net-core razor entity-framework-core


    【解决方案1】:

    您可以通过以下方式做到这一点:

    IQueryable<Table1> table1 = _context.Table1;
    IQueryable<Table2> table2 = _context.Table2;
    IQueryable<Table3> table3 = _context.Table3;
    IQueryable<Table4> table4 = _context.Table4;
    
    var query = 
      from t1 in table1
      join t2 in table2 on t1.Id equals t2.Id into g
      from t2 in g.DefaultIfEmpty()
      join t3 in table3 on t1.Id equals t3.Id into g
      from t3 in g.DefaultIfEmpty()
      join t4 in table4 on t1.Id equals t4.Id into g
      from t4 in g.DefaultIfEmpty()
      select new AllTables
      {
         Table1 = t1,
         Table2 = t2,
         Table3 = t3,
         Table4 = t4
      };
     
    if (!String.IsNullOrEmpty(searchString))
    {
        query = query.Where(s => s.Table1.Id.ToString() == searchString);
    }
    
    //Example for sorting
    switch (sortOrder)
    {
        case "Id":
           query = query.OrderBy(s => s.Table1.Id);
           break;
        case "Name":
           query = query.OrderBy(s => s.Table2.Name);
           break;
    }
    
    var AllTableData = await query.AsNoTracking().ToListAsync();
    

    【讨论】:

    • 我没有考虑查询语法表达式。我之前已将query 移动到搜索字符串和排序上方,但在对最后一行await query.AsNotTracking().ToListAsync() 进行排序后收到错误消息。我尝试了上述方法,并得到了类似的错误:“处理请求时发生未处理的异常。” LINQ 表达式....无法翻译。
    • 虽然我最终让它没有错误地工作,但我不确定它是否是“正确”的方法。使其正常工作的唯一方法是按如下方式进行查询:AllTableData = query.AsEnumerable().OrderBy(s =&gt; s.Table1.Id).toList();
    • 不是很糟糕。我已经更新了以不同方式执行 LEFT JOIN 的答案。
    • 使用您更新的连接查询重新测试。仍然收到 InvalidOperationException: LINQ expression... 无法翻译。不过,您提出的建议比我提出的要好得多。像你一样进行排序/搜索query = query.OrderBy(s =&gt; s.Table1.Id);而不是我在上面的评论中的一个原因是它允许同时进行查询和排序,因为我将查询设置为 AllTableData,它会中断搜索后的任何排序。
    • 我不知道发生了什么。这个查询应该很容易翻译成 SQL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 2022-01-21
    • 2018-11-02
    • 2015-04-04
    • 2016-07-16
    相关资源
    最近更新 更多