我有一个我要显示的视图,我有一个接受字符串(StudentID)的控制器。这是我的控制器动作:
public ActionResult ShowStudent(string StudentID)
{
ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID);
return View();
}
现在,StudentId在其中有前导零。例如00003345,000000223等 因此,要显示特定学生的视图,我必须在网址中输入确切的字符串“00003345”:“http:// Students / ShowStudent / 00003345”即使我输入“我希望能够显示视图” 3345“在网址:”http:// Students / ShowStudent / 3345“但我收到错误。
我尝试传递Long(Int64)参数而不是字符串,并将ViewID转换为ViewData.Model中的String,如:
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));
答案 0 :(得分: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();
}
答案 1 :(得分:2)
如果你的数据库拥有一个大的int,并且你发送的东西更小......你得到的是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();
}
或稍微DRYer:
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 );
}
答案 2 :(得分: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) );
}
答案 3 :(得分: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();
}
我不确定这会增加很多价值。
答案 4 :(得分: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);