"System.String ElementAt[String](System.Collections.Generic.IEnumerable`1[System.String], Int32)" 方法

3

我收到了下面引号中提到的异常。我已经尝试过很多次解决这个问题,但仍然会遇到以下异常。我在stackoverflow上阅读了类似的答案,但它们并不能解决我的问题。在我接收异常的那一行上面,我也进行了注释。

用户代码未处理 System.NotSupportedException 异常 HResult = -2146233067 消息 = LINQ to Entities 不认识 ElementAt[String](System.Collections.Generic.IEnumerable1[System.String], Int32) 方法,这种方法无法转换为存储表达式。 来源 = EntityFramework 堆栈跟踪: at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) ... 在 Neon.DBHandler.registerStudentCourses(String p,List`1 coursesIdSelected)中出错,请参阅 c:\Users\AbdullahABBASI\Desktop\AbbasiWebProject\Neon\Models\DBHandler.cs 的第246行 在 Neon.Student_RegisterCourse.registerbutton_Click(Object sender, EventArgs e) 中出错,请参阅c:\Users\AbdullahABBASI\Desktop\AbbasiWebProject\Neon \ Student_RegisterCourse.aspx.cs的第51行

以下是代码:

internal static void registerStudentCourses(string p, List<string> coursesIdSelected)
{
    AbbasiDatabaseEntities objDB = new AbbasiDatabaseEntities();
    Student objStudent = objDB.Students.Where(s => s.Id == p).FirstOrDefault();
    List<Course> courses = new List<Course>();

    for (int i = 0; i<coursesIdSelected.Count; i++)
    {
        //in the line below i am getting exception mentioned above
        var course = objDB.Courses
            .Where(c => c.Id == (string)coursesIdSelected.ElementAt(i))
            .Select(s=> s)
            .FirstOrDefault();
        courses.Add(course);
    }

    objStudent.Courses = courses;    
} 

LINQ查询在运行时转换为SQL。因此,.ElementAt(i)不可访问。 - PaulShovan
你正在执行一个 SELECT N+1(从技术上讲,这是一个 SELECT N)... 一般来说,这是一种反模式(你正在 for 循环中执行一个 select,因此将会执行 n 个单独的查询到数据库)。 - xanatos
1个回答

8

Entity Framework无法将Where(c => c.Id == (string)coursesIdSelected.ElementAt(i))转换为查询。

引入一个辅助变量以从查询中删除此代码:

for (int i = 0; i<coursesIdSelected.Count; i++){
    string selectedCourse = (string)coursesIdSelected.ElementAt(i);
    var course = objDB.Courses.Where(c => c.Id == selectedCourse).Select(s=> s).FirstOrDefault();
    courses.Add(course);
}

或者将整个循环简化为:

student.Courses = db.Courses.Where(c => coursesIdSelected.Contains(c.Id.ToString()));

1
考虑到 List<string> coursesIdSelectedElementAt() 可以改为 [](然后也许它就可以直接工作了)。 - xanatos
2
第二个更好... 它解决了在 for 循环内部执行 select 的反模式。 - xanatos
最佳解决方案:可爱的阿巴斯爱你。 - Abdullah Jahangir Abbasi

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