【问题标题】:How to handle selected data from LEFT JOIN query?如何处理从 LEFT JOIN 查询中选择的数据?
【发布时间】:2018-05-15 08:30:33
【问题描述】:

我想执行一个查询,选择所有个客户,以及每个客户的对应地址。每个客户可以有零个、一个或多个地址。

这是我尝试过的:

sql = "SELECT customers.*, addresses.* FROM customers LEFT JOIN addresses ON addresses.CustomerId = customers.Id ORDER BY customers.Id OFFSET @start ROWS FETCH NEXT @end ROWS ONLY";

List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@start", limitStart));
parameters.Add(new SqlParameter("@end", limitEnd));
DataSet set = Db.ExecuteSelectQuery(sql, parameters);


DataTable table = set.Tables["customers"];

Console.WriteLine("Tables count: " + set.Tables.Count); // says there's 1 table.

List<Customer> customers = new List<Customer>();

foreach(DataRow row in table.Rows)
{
    Customer cust = new Customer();
    cust.Id = row.Field<int>("Id");
    cust.ClientNumber = row.Field<string>("clientnumber");
    cust.Date = DateTime.Parse(row.Field<string>("date"));
    cust.Firstname = row.Field<string>("firstname");
    cust.Insertion = row.Field<string>("insertion");
    cust.Lastname = row.Field<string>("lastname");

    foreach(DataRow addrRow in /* ......?...... */) // Want to loop through addresses of the current customer row.
    {
        Address address = new Address();
        address.Street = addrRow.Field<string>("Street");
        address.HouseNumber = addrRow.Field<string>("Number");
        address.PostalCode = addrRow.Field<string>("PostalCode");
        address.City = addrRow.Field<string>("City");
        address.Country = 0;// row.Field<int>("CountryCode");

        cust.Addresses.Add(address);
    }

    customers.Add(cust);
}

return customers;

问题是我不知道如何使用SqlClientDataTableDataSet 类来处理查询结果。

我在 Internet 上找不到任何解释如何访问每个客户的选定地址的方法。

谁能给我解释一下,或者给我看一个代码示例?

【问题讨论】:

  • 这可能会有所帮助。您是否定义了两个表之间的关系? msdn.microsoft.com/en-us/library/hbt8xha8(v=vs.110).aspx
  • 当我尝试添加一个DataRelation 时,该关系在其构造函数中要求两个DataColumns。为了访问这些列,我尝试使用set.Tables 来获取一个表,并从该表对象中获取列。但问题之一是该集合仅包含一个表。 (请参阅我的代码的控制台编写)。
  • Db.ExecuteSelectQuery 使用此查询只会在一个表中得到结果,每行都有表客户和地址的字段,在您的循环中检查 customerId 是否与前一个不同,将新客户添加到列表并检查另一个这样的地址列表

标签: c# sql .net sql-server database


【解决方案1】:

您应该过滤属于循环中当前客户的客户的地址

您甚至可以使用if 子句将cust.Idrow.Field&lt;int&gt;("CustomerId") 进行比较

【讨论】:

  • 其实在你的开发中,你有两个数据表。但是您的 SELECT 查询将只生成一张表。如果客户没有多个地址,那么您可以使用您的查询并通过使用“行”对象中的地址字段来更改 .NET 代码。如果没有客户的地址,则与地址相关的“行”字段将为 NULL 。如果一个客户有多个地址,那么您的 SELECT 语句也会为该客户的每个地址复制客户数据。
  • 另外,不要使用“*”,而是简单地添加字段名称,如 customer.id、address.id 作为 addressid 等。如果两个表上有相同名称的字段,这些字段将在查询执行期间导致问题
【解决方案2】:

您可能希望在第二个中为每个使用 linq 库

 foreach(DataRow addrRow in /* ......?...... */) // Want to loop through addresses of the current customer row.
{

像这样:

foreach(DataRow addrRow in table.Rows.Where(x=>x.Field<int>("Id")==cust.Id)) // Want to loop through addresses of the current customer row.
{

您的代码仍会在您的客户列表中生成重复的客户条目,因此可以在第一个 foreach 循环的顶部添加一个条件:

foreach(DataRow row in table.Rows)
{
  if(customers.Where(x=>x.Id == row.Field<int>("Id").Any())continue;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 2016-04-02
    • 2015-01-10
    相关资源
    最近更新 更多