【问题标题】:Filter not working appropriately- when inner joining tables过滤器无法正常工作 - 当内部连接表时
【发布时间】:2020-05-24 03:29:08
【问题描述】:

我有一个可以排序或过滤的分班分数学生列表。 我注意到(视觉上)过滤分数时不会随着他们各自的学生移动,而是 是静态的。

例子-

过滤前:

Student A  |11
Student AA |10
Student B  |09
Student BB |08

被“B”学生过滤后:

Student B  |11
Student BB |10

我假设是因为它们不正确或缺少逻辑,告诉代码学生人数已更改。但是我不确定我需要在代码中添加什么来解决这个问题,并希望这里的人能够指出我正确的方向。

剃刀代码:

@for (int i = 0; i < Model.Students.Count; i++)
                        {
                            <tr>
                                <td>@Model.Students[i].LastName</td>
                                <td>@Model.Students[i].FirstName</td>
                                <td>
                                    @* Ept score form group*@
                                    <div class="form-group">
                                        <input type="hidden" asp-for="@Model.Students[i].Sid" />
                                        <label asp-for="@Model.Students[i].Score.EptScore">Score</label>
                                        <input type="number" data-internalid="@i" asp-for="@Model.Students[i].Score.EptScore" class="form-control limited-width" aria-describedby="helpBlock1" />
                                        <span id="helpBlock1" asp-validation-for="@Model.Students[i].Score.EptScore" class="help-block"></span>
                                    </div>
                                </td>   
                            </tr>

逻辑代码:

IQueryable<Student> StudentsIQ = (from s in _context.Students
                                             where s.StuType == StudentType.New 
                                             && s.YearQuarterEnrolled == quar.Id 
                                             orderby s.LastName, s.FirstName      //default ordering
                                             select s).Include(st => st.Score);

            // Based on input search filters, filter student data
            if (!String.IsNullOrEmpty(LnameSearch))
            {
                StudentsIQ = StudentsIQ.Where(s => s.LastName.ToLower().StartsWith(LnameSearch.ToLower()));
                queryParams.Add("LnameSearch", LnameSearch);
            }
            if (!String.IsNullOrEmpty(SidSearch))
            {
                StudentsIQ = StudentsIQ.Where(s => s.Sid.StartsWith(SidSearch));
                queryParams.Add("SidSearch", SidSearch);
            }
            if (!String.IsNullOrEmpty(FnameSearch))
            {
                StudentsIQ = StudentsIQ.Where(s => s.FirstName.ToLower().StartsWith(FnameSearch.ToLower()));
                queryParams.Add("FnameSearch", FnameSearch);
            }
    ...

【问题讨论】:

  • 不相关提示:您不需要执行ToLower() 来执行不区分大小写的字符串比较。如果这是 Linq-to-Entities,那么默认情况下它已经在进行不区分大小写的比较(根据 SQL 规范)。如果这是 Linq-to-Objects,则使用 StringComparison.OrdinalIgnoreCaseCurrentCultureIgnoreCase。避免使用ToLower 执行比较,因为它会导致在 GC 堆上分配额外的字符串,并且容易受到土耳其语-I 问题的影响。
  • Model.Students 设置为IQueryable&lt;T&gt; 还是你实现了它(首先使用.ToList().ToListAsync()?永远不要通过ViewModel 将IQueryable&lt;T&gt; 暴露给View,因为View 可能在父 IQueryable&lt;T&gt;DbContext 被释放后渲染 - 或者您可能无意中序列化整个数据库表(非常糟糕)。
  • @Dai 谢谢!这是一个超级有用的花絮!
  • @Dai Model.Students 是通过 ToListAsync 物化的 IList,然后被设置为 IList Students (Model.Students)。我们不会将其公开为 IQueryable

标签: c# html asp.net linq razor


【解决方案1】:

您的模型状态已过时,因此您需要在异步调用数据库之前使用ModelState.Clear() 清除它。

【讨论】:

  • 尤里卡!这解决了它!也为任何学习这一点的人详细说明:保存对数据的更改后,模型状态变得无效/陈旧;所以应用程序在最后一个已知点加载页面/数据。在我的 iqueryable 解决问题之前添加:ModelState.Clear();
猜你喜欢
  • 1970-01-01
  • 2013-09-15
  • 2019-11-12
  • 2015-02-14
  • 2013-08-16
  • 2012-11-16
相关资源
最近更新 更多