0

我的数据库中有 [Customer] 和 [Car] 表之间的一对多关系,其中一个客户可能拥有零辆或多辆汽车。

我的项目要求我输出所有客户的列表,其中有一列显示来自汽车的车辆登记 [VehicleReg]。如果客户有多辆汽车,他们的所有车辆登记必须用逗号分隔。如果客户没有汽车,则该列应为空白。

这是查询的基础,但我不知道如何返回注册号。

SELECT [Customer].[FirstName], [CustomerLastName], COMMA SEPARATED VEHICLE REGS FROM [Customer] LEFT JOIN [Car] ON [Customer].[CustomerId] = [Car].[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。

在这个阶段,性能不是主要问题。

到目前为止,我唯一可行的解​​决方案是将车辆登记保存到 [Customer] 表中的列中。虽然这会起作用,但它将涉及手动使新列与 [Car] 表中对车辆登记所做的任何更改保持同步,这并不太难,但一旦我将项目传递给其他人,这可能是一种危险的方法维持。

非常感谢

4

2 回答 2

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
于 2012-06-26T14:36:05.187 回答
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>
于 2012-06-26T14:58:08.953 回答