如何根据字段值从另一个数据表填充一个数据表
本文关键字:数据表 填充 一个 另一个 何根 字段 | 更新日期: 2023-09-27 17:50:46
我教一个9个单元的班,学生可以通过"及格"、"优异"或"优异"来通过每个单元。A P得70分,M 80分,D 90分。全年的总体结果是所有单元的积分之和。
他们需要通过所有的' p '标准,然后才允许'M'标准,他们需要通过所有的'M'标准,然后才允许'D'标准。P/M/D标准的数量因设备而异。以下学生在本单元获得了"及格"(70分),因为他没有通过M,尽管他获得了所有D标准:
第一单元-脑外科
P1 -知道大脑在哪里-传递
P2 -知道哪条路是上的- pass
M1 -解释大脑做什么-通过
M2 -男性和女性的大脑有区别吗- FAIL
找出为什么我的大脑不能解决这个问题-通过
D2 -发明一种药物,可以让大脑立即找出逻辑-通过
D3 -找到一种只用脑力就能赚到很多钱的方法-通过
我有一个SqlDataReader,它用这些列填充一个数据表:unitNo, criterionName, criteriontype(即p/M/D), passsedorfailed。查询已经按单个学生进行选择,因此DataTable只包含一个学生的记录。它看起来像这样:
UnitNo Citerion Type passed?
1 know etc P Yes
1 know etc P Yes
1 explain etc M Yes
1 is there etc M No
1 Figure etc D Yes
1 invent etc D Yes
1 find etc D Yes
2 blah etc P Yes
2 wot etc P Yes
2 so etc M No
和我之后的数据表,看起来像这样:
UnitNo P M D Points
1 Y N Y 70
2 Y Y N 80
3 N N N 0
4 N Y Y 0
5 Y Y Y 90
…
…...........................
最后总分-学生240分。
我对数据表、c#等绝对没问题,是那些该死的逻辑把我搞砸了。我写的每一段代码在大约两行之后看起来都像意大利面。有没有人有一些指针排序这个逻辑吗?就像霍格蒙鬼城学校里的一幕……如果你能解决这个问题,那么我将亲自派你的妻子来给你做周日烤肉。
PC好的,这里是实际的代码与CSharper的答案合并(也编辑添加他的解决方案的额外的列名)。这显然是正确的解决方案,我只是没有完全得到数字的出现(我发现他遗漏了括号后的DataRow,但这不是问题)。我在最后钩上了几个测试网格来显示结果。此外,我不是一个linq家伙,所以我不知道如何将单位名称从第一个表添加到第二个表,或总计点:
(注意,我在passFail字段中使用1=未标记,2 =失败,3 =通过)
//create the sql to extract the data
String sqlString = "SELECT unitNo, unitName, criterionPMD, passFail FROM unitDetails INNER JOIN unitStudentRecord ON unitDetails.id = unitStudentRecord.unitDetailsId INNER JOIN unitSummary ON unitDetails.unitSummaryId = unitSummary.id WHERE studentID = '" + ((String)Session["studentID"]).Trim() + "'";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["studentTutorialsConnectionString"].ConnectionString);
SqlCommand sqlComm = new SqlCommand(sqlString, conn);
conn.Open();
SqlDataReader sqlTotalMarks = sqlComm.ExecuteReader();
//create the workings out datatable and fill it
DataTable dtWorkings = new DataTable();
dtWorkings.Load(sqlTotalMarks);
conn.Close();
// create the results datatable
DataTable dtResults = new DataTable();
dtResults.Columns.Add("units", typeof(int));
dtResults.Columns.Add("name", typeof(string));
dtResults.Columns.Add("P", typeof(bool));
dtResults.Columns.Add("M", typeof(bool));
dtResults.Columns.Add("D", typeof(bool));
dtResults.Columns.Add("points", typeof(int));
//fill the results table
foreach (var units in dtWorkings.Rows.Cast<DataRow>().GroupBy(r => r["unitNo"]))
{
var p = units.Where(r => r["criterionPMD"] == "P").All(r => r["passFail"] == "3");
var m = units.Where(r => r["criterionPMD"] == "M").All(r => r["passFail"] == "3");
var d = units.Where(r => r["criterionPMD"] == "D").All(r => r["passFail"] == "3");
dtResults.Rows.Add(
units.Key,//UnitNo
units.Select(r => r["unitName"]).First(),//UnitName
p,
m,
d,
p ? (m ? (d ? 90 : 80) : 70) : 0);//Points
}
gvTemp.DataSource = dtWorkings;
gvTemp.DataBind();
gvSummary.DataSource = dtResults;
gvSummary.DataBind();
这是gvTemp的网格:
unitNo unitName criterionPMD passFail
2 Computer systems P 3
2 Computer systems P 1
3 Web rubbish P 3
这是gvSummary的网格:
units name P M D points
2 Computer systems 90
3 Web rubbish 90
在gvSummary网格中出现了所有PMD标准的复选框,但没有总数。我原以为第二单元零分,第三单元70分……
oh-so-close…
使用c#类这样做可能有助于将问题结构成更小的部分,并获得更好的可维护解决方案。当然这对于DataTable
也是可能的。数据表的另一个缺点是数据不容易实现类型安全。在这个答案的第一个版本中,缺少r["criterionPMD"]到string的强制类型转换,因此有一个引用比较而不是字符串比较。
//create the workings out datatable and fill it
DataTable dtWorkings = new DataTable();
dtWorkings.Columns.Add("unitNo", typeof(int));
dtWorkings.Columns.Add("unitName", typeof(string));
dtWorkings.Columns.Add("criterionPMD", typeof(string));
dtWorkings.Columns.Add("passFail", typeof(int));
dtWorkings.Rows.Add(2, "Computer systems", "P", 3);
dtWorkings.Rows.Add(2, "Computer systems", "P", 2);
dtWorkings.Rows.Add(3, "Web rubbish", "P", 3);
// create the results datatable
DataTable dtResults = new DataTable();
dtResults.Columns.Add("units", typeof(int));
dtResults.Columns.Add("name", typeof(string));
dtResults.Columns.Add("P", typeof(bool));
dtResults.Columns.Add("M", typeof(bool));
dtResults.Columns.Add("D", typeof(bool));
dtResults.Columns.Add("points", typeof(int));
//fill the results table
foreach (var units in dtWorkings.Rows.Cast().GroupBy(r => r["unitNo"]))
{
var p = units.Where(r => (string)r["criterionPMD"] == "P").All(r => (int)r["passFail"] == 3);
var m = units.Where(r => (string)r["criterionPMD"] == "M").All(r => (int)r["passFail"] == 3);
var d = units.Where(r => (string)r["criterionPMD"] == "D").All(r => (int)r["passFail"] == 3);
dtResults.Rows.Add(
units.Key,//UnitNo
units.Select(r => r["unitName"]).First(),//UnitName
p,
m,
d,
p ? (m ? (d ? 90 : 80) : 70) : 0);//Points
}
使用复杂条件表达式,您可以确保只有在满足所有p, m和d条件时才会给出90分。
即使在只有通过和区分标准的单元中,也会给出正确的结果,因此只有90,70或0分是可能的。我不知道这是不是你的要求。
在只有"p"标准的例子中,很难决定70分还是90分是正确的结果。此代码片段检查是否满足所有P、M和D标准,在这种情况下,即使没有M或D标准并且所有P标准都通过,也会给90分。我想在现实世界中你不会遇到这种情况但无论如何,这值得思考