使用Guid.Parse()方法时为什么会抛出异常?

11

我正在使用WebApi应用程序工作,我编写了一个方法使用以下代码获取学生:

    public Student GetStudent(string studentId)
    {
        var student = this.context.Students.FirstOrDefault(x => x.Id == Guid.Parse(studentId));
        return student;
    }

这里的 studentId 是从 WebApi 调用中获取的。但是,当我尝试运行此应用程序时,它会抛出一个异常,如下所示:

附加信息:LINQ to Entities 不认识方法 'System.Guid Parse(System.String)',因此无法将该方法转换为存储表达式。

请问有人能告诉我为什么会出现这种情况以及如何解决这个问题吗?

4个回答

16

首先,在使用EntityFramework时,它会尝试将Guid.Parse()方法转换为SQL语句,但由于无法将其转换为SQL语句或“存储表达式”,因此转换失败。

您应该将字符串解析从存储表达式中移出,并在查询中使用之前将字符串解析为Guid值。

    public Student GetStudent(string studentId)
    {
        var stdId = Guid.Parse(studentId);
        var student = this.context.Students.FirstOrDefault(x => x.Id == stdId);
        return student;
    }

那么,在LINQ查询中我不能使用任何类型的方法调用吗? - coderhunk
你可以使用EF可以翻译成SQL的方法。这只是EF/L2SQL的工作原理,将LINQ翻译为SQL。 - DevilSuichiro
@Mainul 很好的观察。我希望 EF 能够在内部进行重构,而不必手动操作。 - Anshul

2
您可以尝试这种方法:
public Student GetStudent(string studentId)
{
    var student = (from c in this.context.Students
                  let guidId = Guid.Parse(studentId)
                  where c.Id == guidId
                  select c).FirstOrDefault();

    return student;
}

在这种方法中,let 允许您创建新的临时变量,稍后可能在 LinqToEntities 查询中使用。
我同意 @Mainul 的答案关于异常原因的解释:
首先,当您使用 EntityFramework 时,它会尝试将 Guid.Parse() 方法转换为 SQL,但由于无法将其转换为 SQL 语句/“存储表达式”,因此会失败。

0
更好的做法是,不要使用 string studentId 作为签名,而是使用 Guid studentId,因为这正是你需要的。这样可以清楚地告诉调用者 studentId 是一个 guid,而不是一个 string。如果调用者想要使用返回的 Student 对象,你不希望他这样做:string studentid = student.Id。你希望他这样做:Guid myStudentId = student.Id

0

此处所述

Entity Framework试图在SQL端执行您的投影,但在那里没有等效的string.Format。使用AsEnumerable()强制使用Linq to Objects评估该部分

您的情况尝试评估转换为SQL查询的Guid.Parse,而在SQL中找不到它。

当我尝试操作日期部分时,我也遇到了这个问题-

var query = db.Table.Where(f=> f.Date == paramDate.Date.AddDays(-1)).ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接