0

我有一个要显示的视图,为此我有一个接受字符串(StudentID)的控制器。这是我的控制器操作:

public ActionResult ShowStudent(string StudentID)
{
    ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID);
    return View();
}

现在在这里,StudentId 中有前导零。例如 00003345、000000223 等。因此,要显示特定学生的视图,我必须在 url 中输入确切的字符串“00003345”:“http://Students/ShowStudent/00003345”我希望能够显示即使我在 url 中输入“3345”也可以查看:“http://Students/ShowStudent/3345”,但出现错误。

我尝试传递 Long(Int64) 参数而不是字符串并将 StudentID 转换为 ViewData.Model 中的字符串,例如:

ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID.ToString());

但我收到一个错误:

LINQ to Entities 无法识别方法“System.String ToString()”方法,并且该方法无法转换为存储表达式。

编辑:像这样将其解析为 Int64 有什么问题:

ViewData.Model = student.vwStudent.Where(s => Int64.Parse(s.StudentID) == Int64.Parse(StudentID));
4

5 回答 5

4

下面的工作吗?

public ActionResult ShowStudent(string StudentID)
{
    var padded = StudentID.PadLeft(8, '0');
    ViewData.Model = student.vwStudent.Where(s => s.StudentID == padded);
    return View();
}

或者,如果 StudentID 并不总是添加到 8 个字符,您可能必须使用底层 SQL LIKE 运算符查询所有可能的 StudentID:

var students = student.vwStudent.Where(s => s.StudentID.EndsWith(StudentID));

然后遍历这些结果以寻找正确的匹配。

最后,如果您希望使用底层 SQL IN 运算符将所有可能的匹配项发送到查询以获得精确返回:

public ActionResult ShowStudent(string StudentID)
{
    var possibleStudents = Enumerable.Range(StudentID.Length, 8 - StudentID.Length).Select(l => StudentID.PadLeft(l, '0'));
    ViewData.Model = student.vwStudent.Where(s => possibleStudents.Contains(s.StudentID));
    return View();
}
于 2012-04-11T23:42:58.603 回答
2

如果您的数据库包含一个大整数,并且您发送的内容更小……您将得到一个stack overflow. 您需要将该字符串解析为有用的内容:

ViewData.Model = student.vwStudent.Where(s => s.StudentID == long.Parse(StudentID));

但是,这似乎不是问题(即使问题明确指出“如何将字符串转换为大整数”)。

根据您的描述 ( StudentId's have leading zeros in them) 和您的评论I have to enter it exactly "00003345",我将假设此方法需要一些逻辑。另一方面,我不太确定,因为您的问题表明 StudentIds 的长度不同。?!

public ActionResult ShowStudent(string StudentID)
{
 while( StudentID.Length < 8 )
 {
  StudentID = "0" + StudentID;
 }
 ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID);
 return View();
}

或者更有趣:

public ActionResult ShowStudent(string StudentID)
{
 var x = student.vwStudent.Where(s => s.StudentID == StudentID).FirstOrDefault();
 while( x != null && StudentID.Length < 15)
 {
  StudentID = "0" + StudentID;
  x = student.vwStudent.Where(s => s.StudentID == StudentID).FirstOrDefault();
 }
 ViewData.Model = x;
 return View();
}

或稍微干燥器:

public ActionResult ShowStudent(string StudentID)
{
    Student s;
    while( (s=students.FirstOrDefault( x => x.StudentId == StudentId )) == null ) {
        StudentId = "0" + StudentId;
        if( StudentId.Length > 15 ) break;
    }

    return View( s );
}
于 2012-04-11T23:43:31.360 回答
2

LINQ 需要能够将所有函数转换为底层数据存储,这可能就是您收到该错误消息的原因。但是,如果我正确理解您的问题,您应该能够通过以下方式完成您正在寻找的内容:

public ActionResult ShowStudent(long studentId)
{
    var studentIdStr = studentId.ToString( "D9" );  // 9-digit number, padded w/ zeros
    ViewData.Model = student.vwStudent.Where(s => s.StudentId == studentIdStr);
    return View();
}

顺便说一句,将模型传递给视图的标准方法不是通过设置ViewData.Model,而是将其传递给View方法:

public ActionResult ShowStudent(long studentId)
{
    var studentIdStr = studentId.ToString( "D9" );  // 9-digit number, padded w/ zeros
    return View( student.vwStudent.Where(s => s.StudentID == studentIdStr) );
}
于 2012-04-11T23:44:24.073 回答
1

这是个有趣的问题。如果StudendID 以前导零存储,那么任何内置MVC 函数都将构造具有相同值的URL(即使用前导零)。但是您可以更改 Controller 方法以获取字符串,然后将其转换为 Int64,然后自己添加零.PadLeft(),模型绑定应该仍然有效。

public ActionResult ShowStudent(string StudentID) 
{ 
    string paddedStudentID = Convert.ToInt64(StudentID).ToString().PadLeft(9, '0');
    ViewData.Model = student.vwStudent.Where(s => s.StudentID == paddedStudentID); 
    return View(); 
} 

不过,我不确定这会增加多少价值。

于 2012-04-11T23:46:07.757 回答
0

感谢大家的帮助,我听取了您的一些建议,并得出了一个适合我的解决方案。

我能够通过在我的 SQL 中进行转换来解决这个问题:

CAST(CAST(StudentID AS bigint) AS nvarchar(33)) AS StudentID 

然后在我的控制器中转换它:

var StudentID = Convert.ToString(Int64.Parse(StudentId));

ViewData.Model = student.vwStudent.Where(a => a.StudentID == StudentId);
于 2012-04-13T19:29:42.740 回答