C# 如何在动作参数中将字符串转换为BigInt?

C# 如何在动作参数中将字符串转换为BigInt?,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个要显示的视图,我有一个接受字符串(StudentID)的控制器。以下是我的控制器操作: public ActionResult ShowStudent(string StudentID) { ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID); return View(); } 在这里,StudentId的前导零。e、 g.00003345000000223等。 因此,要显

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

public ActionResult ShowStudent(string StudentID)
{
    ViewData.Model = student.vwStudent.Where(s => s.StudentID == StudentID);
    return View();
}
在这里,StudentId的前导零。e、 g.00003345000000223等。 因此,要显示特定学生的视图,我必须在url中输入准确的字符串“00003345”:http://Students/ShowStudent/00003345即使在url中输入“3345”,我也希望能够显示视图:http://Students/ShowStudent/3345“但是我犯了一个错误

我已尝试传递一个长(Int64)参数而不是字符串,并在ViewData中将StudentID转换为字符串。模型如下:

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));

下面的方法有效吗

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运算符查询所有可能的StudentID:

var students = student.vwStudent.Where(s => s.StudentID.EndsWith(StudentID));
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();
}
然后循环这些结果,寻找正确的匹配项

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

var students = student.vwStudent.Where(s => s.StudentID.EndsWith(StudentID));
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();
}

如果您的数据库包含一个大的int,并且您正在发送一个较小的int…您将得到一个
堆栈溢出。您需要将该字符串解析为有用的内容:

ViewData.Model = student.vwStudent.Where(s => s.StudentID == long.Parse(StudentID));
然而,这似乎不是问题所在(即使问题明确指出“如何将字符串转换为大整数”)

根据您的描述(
StudentId中有前导零)和您的注释
,我必须准确输入“00003345”
,我将假设此方法需要一些逻辑。另一方面,我不太确定,因为你的问题说学生的长度不同

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

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
,而是将其传递到
视图
方法:

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) );
}

这是一个有趣的问题。如果studendId与前导零一起存储,那么任何内置MVC函数都将使用相同的值来构造URL(意思是带前导零的)。但是,您可以将控制器方法更改为获取字符串,然后将其转换为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(); 
} 

不过,我不确定这是否有多大价值。

谢谢大家的帮助,我听取了你们的建议,找到了一个适合我的解决方案

我可以通过在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);

如果值是string,则无需再次调用
ToString()
。但是您提到,当您尝试在没有前导零的情况下使用该资源时,出现了一个错误。。那是什么样的错误?我认为你不应该在那里使用
Long
。。也许这是一个格式化参数加上零的问题。。你能显示你在尝试时遇到的错误吗?@MilkyWayJoe对不起,当我输入没有前导零的学生id时,我没有收到错误,它不会显示任何结果。我必须准确地输入“00003345”,那么你为什么不尝试在你的操作中添加缺少的零呢?(在操作中,但在将参数传递到查询之前)或在渲染视图时添加零(在get操作中)?@MilkyWayJoe另外,当我将StudentID参数更改为“Int64”而不是“string”时,我正在调用ToString()。将参数类型更改为“Int64”后,如果我不调用ToString(),它会给出错误:委托'System.Func'不接受一个参数:s=>s.StudentID==StudentID);给你。。人们正在回答我告诉你的问题:PStudentId不是9的固定长度。根据你的问题,我的理解是它被存储为一个带前导零的固定长度字符串。无论固定长度有多长,都可以将9替换为可变长度。我应该通过将StudentId列设置为固定长度来实现它吗?我认为这是明智的……如果要实现字符串相等,003不同于03,03不同于3,因此除非底层存储能够在进行比较之前将其转换为数字形式,否则我认为最好使用固定宽度。更好的办法是将学生ID存储为一个数字,而不是字符串。@我无权更改表中的数据类型,但是我将尝试与这里的数据库人员交谈。我非常怀疑他们会对数据类型进行任何更改。因此,想要一个由我控制的替代解决方案。@Yamen有没有办法解决存储在同一列中没有前导零的数字?我应该如何显示没有前导零填充的数字?是的,在基础SQL中,您希望最终的查询在LINQ
中查找像“%9999”这样的
StudentId。其中(s=>s.StudentId.EndsWith(StudentId)
。当然,您可以得到多个结果,您需要搜索精确匹配的结果。@yamen是的,EndsWith将起作用,但并不总是这样,需要找到一个解决方案,只显示输入的学生。OK添加了最后一个选项,该选项构建所有可能的学生ID组合,并检查所有学生ID的精确匹配m使用Contains(SQL IN运算符)。@yamen您的查询仍将显示所有可能的学生。例如:如果学生id为00222323和2323,则将同时显示这两个id。是否有一种方法可以寻址存储在同一列中没有前导零的数字?此列中有前导零的学生id