如何根据字段值从另一个数据表填充一个数据表

本文关键字:数据表 填充 一个 另一个 何根 字段 | 更新日期: 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分。我想在现实世界中你不会遇到这种情况但无论如何,这值得思考