【问题标题】:how concatenate multiple rows in LINQ with two tables?如何将 LINQ 中的多行与两个表连接起来?
【发布时间】:2016-01-27 17:18:31
【问题描述】:

我尝试将单行中的多行与 2 个表连接起来,其中一个表有一个外键

我有这张桌子:

台式打印机:

PrinterID    Name      Description 
--------------------------------
1          Printer1   Description1
2          Printer2   Description2

表格分辨率:

ResolutionID    Measure    PrinterId
--------------------------------
1              123            1
2              234            1
3              345            2
4              456            2

我在 GridView 中需要这个:

PrinterID          Name              Description          Resolution
------------------------------------------------------------------------
1                 Printer1           Description1          123, 234
2                 Printer2           Description2          345, 456

我有这个代码,但我卡住了

    var Printer = from tPrinter in Context.Printer
                  join tResolution in Context.Resolution on tPrinter.PrinterId equals tResolution.PrinterId into collection2
                  from subcase2 in collection2.DefaultIfEmpty()
                  where tPrinter.DisableDate == null

                  select new
                  {
                      tPrinterPrinterId = tPrinter.PrinterId,
                      tPrinterName = tPrinter.Name,
                      tPrinterDescription = tPrinter.Description,
                      tCountryName = tPrinter.City1.State.Country.Name,
                      tStateName = tPrinter.City1.State.Name,
                      tCityName = tPrinter.City1.Name
                  };

  return Printer

【问题讨论】:

  • 不应该是tprinter.PrinterId吗?在线:on Printer.PrinterId equals tRe...
  • 是的,你是对的,很抱歉这个错误
  • 现在可以用了吗?
  • 你使用EntityFramework吗?以及如何打开上下文?
  • 是的,连接不是问题,实体适用于所有其余查询

标签: c# asp.net linq


【解决方案1】:

连接会为打印机和分辨率的每个组合创建一行。我想你想在子查询中选择它。

var Printer = from tPrinter in Context.Printer
              where tPrinter.DisableDate == null

              select new
              {
                  tPrinterPrinterId = tPrinter.PrinterId,
                  tPrinterName = tPrinter.Name,
                  tPrinterDescription = tPrinter.Description,
                  tCountryName = tPrinter.City1.State.Country.Name,
                  tStateName = tPrinter.City1.State.Name,
                  tCityName = tPrinter.City1.Name,
                  resolution = Context.Resolution.Where(r => r.PrinterId == tPrinter.PrinterId)
              };

return Printer;

完成ToList() 将其从数据库中取出后,您就可以String.Join(", ", printer.resolution) 创建一个逗号分隔列表。

【讨论】:

  • 如果你使用 LINQ to Entities 这个String.Join 将不起作用,因为 EF 不知道如何在 SQL 查询中翻译它。您必须首先使用ToList() 或更好的Take(10) 获取结果,然后应用String.Join
  • @MihailStancescu 你是对的,谢谢你提醒我。我已经更新了答案。
  • soyyy,但不适用于:分辨率 = String.Join(", ", Context.Resolution.Where(r => r.PrinterId == tPrinter.PrinterId).ToList())
  • 有人帮帮我请 xD
  • 您实际上仍在尝试创建 SQL 调用的 LINQ-to-SQL 调用中。它不理解String.Join,也不理解ToList()。您必须将信息作为查询中的值列表获取,然后在运行Printer.ToList() 之后,您可以执行String.Join(", ", p.resolutions)。您也可以运行ToList(),然后使用另一个.Select() 语句以您想要的格式返回分辨率。
【解决方案2】:
var Printer = Context.Printer.Join(Context.Resolution, p => p.PrinterID, r => r.PrinterId, (p, r) => new
        {
            PrinterId = p.PrinterID,
            Name=p.Name,
            Description=p.Description,
            Resolution = String.Join(", ", Context.Resolution.Where(k => k.PrinterId == p.PrinterID).Select(lm => lm.Measure.ToString()))
        }).Distinct();

【讨论】:

    【解决方案3】:

    这可能不是您所要求的,但如果您使用模型绑定,您可以在没有任何复杂 linq 的情况下以这种方式显示数据。这是可行的,因为模型应该知道打印机具有与其关联的分辨率集合(来自外键关系)。

    <asp:GridView ID="GridView1" runat="server" ItemType="Business.Models.Printer" SelectMethod="SelectPrinters" Style="margin-left: 30px" AutoGenerateColumns="False">
        <Columns>
            <asp:BoundField DataField="PrinterID" HeaderText="Id"/>
            <asp:TemplateField HeaderText="Resolution">
                <ItemTemplate>
                    <asp:DataList ID="Resolutions"
                        RepeatDirection="Horizontal"
                        RepeatLayout="Table"
                        RepeatColumns="0" runat="server" ItemType="Business.Models.Resolution" DataKeyNames="ResolutionID" DataSource='<%# Item.Resolutions %>' >
                        <ItemTemplate>
                            <asp:Label ID="lblResolutions" runat="server"> <%#Item.Resolution.Measure %></asp:Label>
                        </ItemTemplate>
    
                        <SeparatorTemplate>
                            ,
                        </SeparatorTemplate>
    
                    </asp:DataList>
    
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    

    选择方法:

        public IQueryable<Printers> SelectPrinters()
        {
            var query = dbContext.Printers;
            return query;
        }
    

    【讨论】:

      猜你喜欢
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      相关资源
      最近更新 更多