【问题标题】:Contains only working partially C#, MVC仅包含部分工作的 C#、MVC
【发布时间】:2015-11-15 10:13:36
【问题描述】:

我有一个员工下拉列表供用户选择。当用户选择员工时,我会将值与数据库中的值进行比较。如果所选值包含员工的名字和姓氏,那么我应该能够提取他们各自的员工 ID。

我的问题是我正在使用 .Contains,它只捕获一些员工姓名,即使他们都使用相同的大小写,并且不可能出现诸如额外空格之类的错误,因为员工列表是由我与之比较的同一张表填充以查找 ID。

 [HttpPost]
    public ActionResult Create(AppViewModel app, App appl, string selectedEmployee)
    {
        //Grabs the value of the selected employee.
        selectedEmployee = Request.Form["selectEmployee"].ToString();

        try
        {
            //TODO: Add insert logic here
            var emp = Database.Session.Query<Employee>().AsEnumerable();

            appl.AppOwnerID = (from e in emp
                               where selectedEmployee.Contains(e.EmpFirstName) && selectedEmployee.Contains(e.EmpLastName)
                               select e.EmplID).First();



            using (ITransaction transaction = Database.Session.BeginTransaction())
            {
                Database.Session.Save(appl);
                transaction.Commit();
            }
            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {

            return View();
        }
    }

由于某种原因,当我选择某些员工时,它能够找到他们的 ID,并且运行良好,但对于其他员工,它返回 " " 作为它的值,因为 Contains 方法找不到他们的名字和姓氏。

更新:这是我的列表创建和填充的地方。正如大家提到的使用 trim 时,我添加了 trim 方法,用于在列表中添加对象时,以及将其添加到我将所选值与数据库值进行比较的位置。

 // GET: App/Create
    public ActionResult Create(string selectEmployee)
    {
        //Holds all employees
        var emp = Database.Session.Query<Employee>().AsEnumerable();

        //Orders employees by last name.
        var empOrdered = emp.OrderBy(e => e.EmpLastName);


        //Formats Employees Names and creates array
        var empName = (from e in empOrdered
                       select e.EmpFirstName + " " + e.EmpLastName).ToArray();

        //List to hold employee names
        var empList = new List<string>();

        //Loops through array to add names into list
        foreach (string empl in empName)
        {
            empList.Add(empl.Trim());
        }

        ViewBag.selectEmployee = new SelectList(empList);

        var model = new AppViewModel();

        return View(new AppViewModel());
    }

第二次更新:这是我对控制器的看法。

 @model App_Catalog.Models.AppViewModel
@{
    ViewBag.Title = "Create";
 }

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>AppViewModel</h4>
        <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.AppName, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.AppName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.AppName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Owner, htmlAttributes: new { @class =      "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("selectEmployee", "Please Select an Employee")
        </div>

    </div>

【问题讨论】:

  • 难道你误解了First()的用法?另外,selectedEmployee = Request.Form["selectEmployee"].ToString();这行的目的是什么?
  • 您确定所选的员工姓名与数据库中的姓名完全相同吗?如果直接对数据库运行 SQL 查询,是否会得到类似的结果?
  • 你为什么不使用 Where 而不是 Contains ?即在 selectedEmployee 中还有什么,你从下拉列表中得到了什么?
  • 多久刷新一次? "var emp = Database.Session.Query().AsEnumerable();"
  • @Casper:使用同一行代码在 Http Get 方法中填充该列表,以从数据库中获取所有员工。所以我想每次用户访问页面时它都会刷新

标签: c# asp.net-mvc linq contains


【解决方案1】:

如何根据小写值验证您的包含? 例如(可优化代码)如下:

 where selectedEmployee.ToLowerCase().Contains(e.EmpFirstName.ToLowerCase()) &&
       selectedEmployee.ToLowerCase().Contains(e.EmpLastName.ToLowerCase())

【讨论】:

  • 我试过像你说的那样使用 ToLower(),但是没有用。
【解决方案2】:

也许修剪您的 e.EmpFirstNamee.EmpLastName 字段,因为它们可以用空格填充。我已经看过很多次了,这可能会引起很多混乱。

【讨论】:

  • 我尝试修剪它,但它仍然传递一个空值。
【解决方案3】:

首先 - 将您的 Controller 签名更改为:

public ActionResult Create(AppViewModel app, App appl, string selectEmployee)

当你这样做时,MVC 会自动绑定 selectEmployee 变量,你不再需要这个字符串了:

//Grabs the value of the selected employee.
selectedEmployee = Request.Form["selectEmployee"].ToString();

关于您的查询,我相信您正在尝试这样做:

appl.AppOwnerID = emp.FirstOrDefault(e => selectEmployee.Contains(e.EmpFirstName)
                  && selectEmployee.Contains(e.EmpLastName)).EmplID;

正如这里所说的 - 可能是您的员工姓名和姓氏中有一些空格。使用Trim() 函数确保不是您的问题。

appl.AppOwnerID = emp.FirstOrDefault(e => selectEmployee.Contains(e.EmpFirstName.Trim())
                  && selectEmployee.Contains(e.EmpLastName.Trim())).EmplID;

【讨论】:

  • 由于某种原因,我无法让 lambda 表达式工作。我对 lambdas 了解不足,无法自己解决问题。我在 .Select 部分收到一个错误,指出我的模型不包含“选择”的定义。有什么建议吗?
  • 感谢指正。不幸的是,这也不起作用。
  • @bongo700 您是否检查了控制器的调试结果?我也无法理解你在这行Database.Session.Query&lt;Employee&gt;().AsEnumerable()做什么?
  • 该行在数据库中查询我的员工表以获取所有值。我有一个映射到该表的 Employee 模型。当我调试控制器时,它会显示正在传递的值“”,而不是员工的姓名。正如我在原始帖子中提到的,当我选择某些员工时,它实际上将他们的姓名作为值传递,但对于其他员工,它传递“”。这就是我的困惑。
  • @bongo700 好的,似乎是客户端的问题,请展示您的观点
【解决方案4】:

为什么不在检查数据库之前删除所有空格并修剪每个要检查的字符串的两侧。

selectEmployee = selectEmployee.Replace(" ", "").Trim(); 

在尝试使用 contains 匹配之前,对从数据库中提取的记录执行相同操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多