我有这个简单的SQL查询:
SELECT CustomerName, OrderId
FROM Customer c
LEFT JOIN Orders o ON o.CustomerId = c.CustomerId
我需要从查询结果中填充我的Customer实体:
public class Customer
{
public string Name { get; set; }
public IEnumerable<int> OrderIds { get; set; }
}
我正在使用SqlDataReader读取数据:
using(SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Customer c = new Customer();
c.Name = rdr["CustomerName"].ToString();
yield return c;
}
}
问题:在不使用ORM的情况下,填写 OrderIds 属性的最简单,最简洁的方法是什么?左连接导致查询返回每个客户多行(因为每个客户有多个订单)所以现在逐行读取它就像上面的代码一样不起作用?有没有办法填充该实体,仍然使用收益率返回延期执行?
答案 0 :(得分:2)
第一版:
var customersRDR = from rCustomers in rdr.Cast<DbDataRecord>()
group rCustomers by rCustomers["CustomerName"] into custGroups
select new Customer
{
Name = (string)custGroups.Key,
OrderIds = from c in custGroups select (Int32)c["OrderId"]
};
第二版:
DataTable dt = new DataTable();
dt.Load(rdr);
var customers = from c in dt.AsEnumerable()
group c by c["CustomerName"] into custGroups
select new Customer{
Name = custGroups.Key.ToString(),
OrderIds = from c in custGroups select Convert.ToInt32(c["OrderId"])
};
第3版:
DataTable dt = new DataTable();
dt.Load(rdr);
var customerGroups = dt.AsEnumerable()
.GroupBy(c => c["CustomerName"]);
foreach (var customer in customerGroups){
Customer cust = new Customer();
cust.Name = customerGroup.Key.ToString();
cust.OrderIds = from c in customerGroup select Convert.ToInt32(c["OrderId"]);
}
答案 1 :(得分:1)
List<int> orderIds = (from IDataRecord r in rdr
where (string) r["CustomerName"] == c.Name
select (int)r["OrderIds"]).ToList();
修改强>
如果没有ORM,这有点棘手。然而,另一种选择是使用多个阅读器。它需要您有两个查询 - 一个用于客户,一个用于订单。举个例子:
private void GetCustomerWithOrders()
{
using (var conn = new SqlConnection("your connection string"))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT CustomerName, CustomerId FROM Customer";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var customerId = reader.GetInt32(1); // CustomerId
List<int> orders = GetOrders(customerId);
}
}
}
}
}
private List<int> GetOrders(int customerId)
{
var orders = new List<int>();
using (var conn = new SqlConnection("your connectionstring"))
{
using (var cmd = new SqlCommand("SELECT OrderId FROM Orders WHERE CustomerId = @CustomerId", conn))
{
var param = new SqlParameter
{
ParameterName = "@CustomerId",
Value = customerId
};
cmd.Parameters.Add(param);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var orderId = reader.GetInt32(0); // OrderId
orders.Add(orderId);
}
}
}
}
return orders;
}
答案 2 :(得分:0)
var dataReader = cmd.ExecuteReader();
var dataTable = new DataTable();
dataTable.Load(dataReader);