2012-06-26 84 views
0

我在[Customer]和[Car]表之間的數據庫中有一對一關係,其中一個客戶可能有零個或多個汽車。C#MS Access查詢返回字符串聚合

我的項目需要我輸出所有客戶的列表,其中列出了單個列,顯示汽車的車輛註冊[VehicleReg]。如果客戶擁有多輛汽車,則其所有車輛註冊必須以英文逗號分隔。如果客戶沒有汽車,那麼該欄應該是空白的。

這是查詢的基礎,但我不能解決如何返回註冊號碼。

SELECT [客戶] [姓名],[CustomerLastName],逗號分隔VEHICLE REGS FROM [客戶] LEFT JOIN [汽車] ON [客戶]。[客戶] = [汽車]。[fkCustomerId]

我要找的輸出會是這樣

FirstName | LastName | VehicleRegistrations 
------------------------------------------------- 
John  | Smith  | MY51 4RT 
Joe   | Mason  | MU08 5TH 
Connor  | Norman  | 
Graham  | Naughton | HT09 6TY, HT11 8UQ 
Lilly  | Adams  | JK55 8HY 

我使用的MS Access數據庫1997年,C#和.NET 4.0。

表現在這個階段不是主要問題。

我目前唯一的工作解決方案是將車輛註冊保存到[客戶]表中的一列。雖然這可以起作用,但它會涉及手動將新列與[Car]表中的車輛註冊所做的任何更改保持同步,這並不是太困難,但是一旦我將項目傳遞給其他人,這可能是一種危險的方法保持。

非常感謝

+0

嘗試這一點,它可以幫助,通過'http:// stackoverflow.com/A/1048235/405673' –

+0

@Furqan,請問在這種情況下TSQL工作(MDB/.NET 4)? – nicholas

+0

你在哪裏輸出這些數據?在勝利表單應用程序上的datagridview? – nicholas

回答

1

你需要一個輔助功能,以實現這一

Public Function JoinFromRecordset(_ 
    DataSource As String, Optional Delimiter As String = ";", _ 
    Optional Columns As Long = 1) As String 

    Dim db As DAO.Database, rs As DAO.Recordset, s As String, col As Long 

    Set db = CurrentDb 
    Set rs = db.OpenRecordset(DataSource, dbOpenForwardOnly) 
    Do Until rs.EOF 
     For col = 0 To Columns - 1 
      If s = "" Then 
       s = Nz(rs(col)) 
      Else 
       s = s & Delimiter & Nz(rs(col)) 
      End If 
     Next col 
     rs.MoveNext 
    Loop 
    rs.Close: Set rs = Nothing 
    db.Close: Set db = Nothing 
    JoinFromRecordset = s 
End Function 

現在你可以寫

SELECT FirstName, CustomerLastName, 
    JoinFromRecordset('SELECT VehicleReg FROM Car WHERE fkCustomerId=' & 
     CustomerId) As VehicleRegistrations 
FROM Customer 
+0

很好的建議。只是檢查,用戶打算從.NET應用程序運行選擇查詢。大概這意味着函數是在mdb中定義的,並且表適配器是否能夠調用自定義函數? – nicholas

+0

對不起,我錯過了。我的建議只適用於Access應用程序。 –

+0

+1;正在尋找比我寫的「DConcat」功能更優雅的解決方案。我喜歡這給你的控制。它也可以用ADODB :: Recordset :: GetString()寫入 – transistor1

0

我會存到數據庫,因爲它是和運行報告在您的應用程序中進行操作,類似於下面的操作,使用Northwind數據庫並將客戶加入訂單,並使用訂單ID代替您的註冊號碼呃。

創建兩個類:

public class Customer 
{ 
    public string Name { get; set; } 
    public IEnumerable<Order> Orders { get; set; } 
} 

public class Order 
{ 
    public int Id { get; set; } 
} 

爲您的數據創建數據集,與數據表的客戶和訂單和外鍵的表之間的關係。我使用了一個類型化的數據集來自動創建適配器,但如果您手動滾動,則適用相同的原則。

創建一個ViewModel類來獲取數據並對其進行排列。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace SO_StringAggregate 
{ 
    public class ViewModel 
    { 
     public ViewModel() 
     { 
      // populate the data set 
      var dataSet = new NorthwindDataSet(); 
      using (var customersAdp = new NorthwindDataSetTableAdapters.CustomersTableAdapter()) 
      using (var ordersAdp = new NorthwindDataSetTableAdapters.OrdersTableAdapter()) 
      { 
       customersAdp.Fill(dataSet.Customers); 
       ordersAdp.Fill(dataSet.Orders); 
      } 

      // populate your domain objects 
      var customers = dataSet.Customers.ToArray().Select(cust => new Customer 
      { 
       Name = cust.Company_Name, 
       Orders = cust.GetOrdersRows().Select(order => new Order { Id = order.Order_ID }) 
      }); 

      this.Customers = customers; 

      // build the report 
      StringBuilder report = new StringBuilder(); 
      string formatString = "{0,-30}|{1}"; 

      report.Append(string.Format(formatString, "Name", "Order Ids")); 
      report.Append(Environment.NewLine); 
      Customers.ToList().ForEach(cust => report.AppendLine(string.Format(
       formatString, 
       cust.Name, 
       string.Join(",", cust.Orders.Select(o => o.Id).ToArray())) 
       )); 

      // display the report 
      Report = report.ToString(); 
     } 

     public IEnumerable<Customer> Customers { get; set; } 

     public string Report { get; set; } 

    } 
} 

然後,您可以在綁定到Report屬性的視圖中顯示數據。

<Window x:Class="SO_StringAggregate.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBox FontFamily="Consolas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Report}" /> 
    </Grid> 
</Window> 
+0

上面沒有看到你的UltraWinGrid註釋。在這種情況下,在Customer類上創建一個返回string.Join(「,」,this.RegistrationNumbers.ToArray())的JoinedReg屬性 –