比较数据集C#中不同表的行
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比较数据集C#中不同表的行相关的知识,希望对你有一定的参考价值。
我是SQL和C#的新手,我一直在寻找我遇到的问题的答案,但找不到完全解决它的问题。
我有一个链接到SQL Server数据库的C#应用程序。在我的数据库中,我有2个表,一个包含客户信息,另一个包含其帐户信息。如果特定客户没有帐户,则第二个表每个客户可以有超过1行,甚至没有行。
这是两个表:
客户表:
账户信息表:
预期产出将是:
Franklin, Ben ($32)
Jones, Thomas ($5)
Tesla, Tesla
我正在尝试编写一种方法,将所有客户加载到列表以及他们的帐户信息,但我收到每个客户的错误帐户信息(即Chequing和Saving)。当客户没有帐户或我正在比较的行具有不同的客户编号时,就会发生这种情况。所有名字都在我的名单上,但帐号信息错误。有更简单的方法吗?或者我做错了什么?我真的很感激任何帮助。
这是代码:
public List<CustomerAccountManager> LoadAllCustomers()
{
SqlCommand cmd1, cmd2;
SqlDataAdapter sqlda;
DataSet sqlds = new DataSet();
decimal? Chequing = null;
decimal? Saving = null;
int CustomerNumber = 0;
string FirstName = string.Empty;
string LastName = string.Empty;
List<CustomerAccountManager> AllCustomers = new List<CustomerAccountManager>();
cmd1 = new SqlCommand("SELECT Customer.CustomerNumber, FirstName, LastName FROM Customer", Connection);
cmd2 = new SqlCommand("SELECT Account.CustomerNumber, AccountType, Balance FROM Account WHERE AccountType = 'C' OR AccountType = 'S' ", Connection);
sqlds.Tables.Add("Customers");
sqlds.Tables.Add("Acct");
sqlda = new SqlDataAdapter(cmd1);
sqlda.Fill(sqlds.Tables["Customers"]);
sqlda = new SqlDataAdapter(cmd2);
sqlda.Fill(sqlds.Tables["Acct"]);
foreach (DataRow cust in sqlds.Tables[0].Rows)
{
foreach (DataRow acct in sqlds.Tables[1].Rows)
{
CustomerNumber = Convert.ToInt32(cust["CustomerNumber"]);
int CustomerNumberAcct = Convert.ToInt32(acct["CustomerNumber"]);
if (CustomerNumber == CustomerNumberAcct)
{
CustomerNumber = Convert.ToInt32(cust["CustomerNumber"]);
FirstName = Convert.ToString(cust["FirstName"]);
LastName = Convert.ToString(cust["LastName"]);
string AcctType = Convert.ToString(acct["AccountType"]);
if (AcctType == "C")
Chequing = Convert.ToDecimal(acct["Balance"]);
if (AcctType == "S")
Saving = Convert.ToDecimal(acct["Balance"]);
}
else
{
for (int index = 0; index < sqlds.Tables[0].Rows.Count; index++)
{
DataRow search = sqlds.Tables[0].Rows[index];
int customernosearch = Convert.ToInt32(search["CustomerNumber"]);
if (customernosearch == CustomerNumberAcct)
{
CustomerNumber = Convert.ToInt32(acct["CustomerNumber"]);
FirstName = Convert.ToString(cust["FirstName"]);
LastName = Convert.ToString(cust["LastName"]);
string AcctType = Convert.ToString(acct["AccountType"]);
if (AcctType == "C")
Chequing = Convert.ToDecimal(acct["Balance"]);
else
Chequing = null;
if (AcctType == "S")
Saving = Convert.ToDecimal(acct["Balance"]);
else
Saving = null;
}
}
}
}
AllCustomers.Add(new CustomerAccountManager(CustomerNumber, FirstName, LastName, Chequing, Saving));
}
return (AllCustomers);
}
答案
如果我理解你的正确性比你的查询看起来像这样
declare @customer table (number int, firstname varchar(50), lastname varchar(50))
declare @account table (number int, acctype varchar(50), balance decimal(16,2))
insert into @customer (number, firstname, lastname)
values (100000, 'Ben', 'Franklin'), (100001, 'Thomas', 'Jones'), (100002, 'Tesla', 'Tesla')
insert into @account (number, acctype, balance)
values (100000, 'C', 26), (100000, 'S', 6), (100001, 'C', 5)
SELECT c.Number, c.FirstName, c.LastName,
ac.Balance AS CheckBalans,
ac2.Balance AS SavingBalans,
isnull(ac.Balance, 0) + isnull(ac2.Balance, 0) as total
FROM @customer c
LEFT JOIN @account ac ON ac.Number = c.Number
AND ac.AccType = 'C'
LEFT JOIN @account ac2 ON ac2.Number = c.Number
AND ac2.AccType = 'S'
结果就是这样
Number FirstName LastName CheckBalans SavingBalans total
------ --------- -------- ----------- ------------ -----
100000 Ben Franklin 26 6 32
100001 Thomas Jones 5 null 5
100002 Tesla Tesla null null 0
请记住,当有更多帐户类型时,此查询将不再有效
另一答案
这不是最好的做事方式,但我会坚持你的代码。只需删除else
部分,就会弄乱一切。第一个if (CustomerNumber == CustomerNumberAcct)
部分正在完成这项工作。
提示:您无需在DataSet
中手动创建表格,Fill()
函数将自动创建它们。
public List<CustomerAccountManager> LoadAllCustomers() {
SqlCommand cmd1, cmd2;
SqlDataAdapter sqlda;
DataSet sqlds = new DataSet();
decimal? Chequing = null;
decimal? Saving = null;
int CustomerNumber = 0;
string FirstName = string.Empty;
string LastName = string.Empty;
List<CustomerAccountManager> AllCustomers = new List<CustomerAccountManager>();
cmd1 = new SqlCommand("SELECT Customer.CustomerNumber, FirstName, LastName FROM Customer", Connection);
cmd2 = new SqlCommand("SELECT Account.CustomerNumber, AccountType, Balance FROM Account WHERE AccountType = 'C' OR AccountType = 'S' ", Connection);
//sqlds.Tables.Add("Customers");
//sqlds.Tables.Add("Acct");
sqlda = new SqlDataAdapter(cmd1);
sqlda.Fill(sqlds.Tables["Customers"]);
sqlda = new SqlDataAdapter(cmd2);
sqlda.Fill(sqlds.Tables["Acct"]);
foreach (DataRow cust in sqlds.Tables[0].Rows) {
foreach (DataRow acct in sqlds.Tables[1].Rows) {
CustomerNumber = Convert.ToInt32(cust["CustomerNumber"]);
int CustomerNumberAcct = Convert.ToInt32(acct["CustomerNumber"]);
if (CustomerNumber == CustomerNumberAcct) {
CustomerNumber = Convert.ToInt32(cust["CustomerNumber"]);
FirstName = Convert.ToString(cust["FirstName"]);
LastName = Convert.ToString(cust["LastName"]);
string AcctType = Convert.ToString(acct["AccountType"]);
if (AcctType == "C")
Chequing = Convert.ToDecimal(acct["Balance"]);
if (AcctType == "S")
Saving = Convert.ToDecimal(acct["Balance"]);
}
}
AllCustomers.Add(new CustomerAccountManager(CustomerNumber, FirstName, LastName, Chequing, Saving));
}
return (AllCustomers);
}
或者,您可以使用LINQ在一行中实现所有这些功能。
编辑如果你想以同样的方式继续这样做,我建议将你的SQL查询合并到一个让你的生活更轻松的问题。像这样:
public List<CustomerAccountManager> LoadAllCustomers() {
string sql;
SqlCommand cmd;
SqlDataAdapter sqlda;
DataSet sqlds = new DataSet();
decimal? Chequing = null;
decimal? Saving = null;
int CustomerNumber = 0;
string FirstName = string.Empty;
string LastName = string.Empty;
List<CustomerAccountManager> AllCustomers = new List<CustomerAccountManager>();
sql = @"SELECT c.CustomerNumber, c.FirstName, c.LastName,
ca.Balance AS Chequing, sa.Balance AS Saving
FROM Customer c
LEFT JOIN Account ca ON ca.CustomerNumber = c.CustomerNumber
AND ca.AccountType = 'C'
LEFT JOIN Account sa ON sa.CustomerNumber = c.CustomerNumber
AND sa.AccountType = 'S'";
cmd = new SqlCommand(sql, Connection);
sqlda = new SqlDataAdapter(cmd);
sqlda.Fill(sqlds);
foreach (DataRow cust in sqlds.Tables[0].Rows) {
CustomerNumber = Convert.ToInt32(cust["CustomerNumber"]);
FirstName = Convert.ToString(cust["FirstName"]);
LastName = Convert.ToString(cust["LastName"]);
Chequing = Convert.ToDecimal(cust["Chequing"]);
Saving = Convert.ToDecimal(cust["Saving"]);
AllCustomers.Add(new CustomerAccountManager
(CustomerNumber, FirstName, LastName, Chequing, Saving));
}
return (AllCustomers);
}
以上是关于比较数据集C#中不同表的行的主要内容,如果未能解决你的问题,请参考以下文章