代码之家  ›  专栏  ›  技术社区  ›  user584018

尝试获取StudentId=1的“分数”时出错

  •  0
  • user584018  · 技术社区  · 5 年前

    我有以下实体和数据库上下文类,

    public class Grade
    {
        public int Id { get; set; }
        public string GradeName { get; set; }
    
        public virtual ICollection<Student> Students { get; set; } = new HashSet<Student>();
    }
    
    public class Student
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
    }
    
    
    
    public class SchoolContext : DbContext
    {
        public DbSet<Grade> Grades { get; set; }
        public DbSet<Student> Students { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=SchoolDB;Trusted_Connection=True;");
        }
    }
    

    在执行下面的代码时遇到下面的错误,这里需要做什么。谢谢

    我在寻找解决方案,但不在学生课堂上添加年级属性

    系统InvalidOperationException:“包含属性lambda表达式”x=>{from Student c in x.Student where([c].Id==u studentId_0)select[c]}无效。表达式应表示属性访问:“t=>t、 “我的财产”。要将在派生类型上声明的导航作为目标,请指定目标类型的显式类型lambda参数,例如“(派生d)=>d、 “我的财产”。有关包含相关数据的更多信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=746393 .'

    static void Main(string[] args)
        {
            var studentId = 1;
    
            var context = new SchoolContext();
            var data = context.Grades.Include(x => x.Students.Where(c => c.Id == studentId)).SingleOrDefault();
        }
    

    enter image description here

    0 回复  |  直到 5 年前
        1
  •  2
  •   Ivan Stoev    5 年前

    我在寻找解决方案,但不在学生课堂上添加年级属性

    所以你想得到 Grade 暂时 Student ,但不想添加 等级 导航属性到 大学生 让EF Core自然地为你处理这些?换句话说,失去了ORM最大的好处之一,开始为ORM可以用简单属性访问器处理的简单请求寻找SQL-ish解决方案?

    有很多方法可以满足你的需求,但我建议你先问问自己是否真的需要。

    无论如何,一种可能的解决方案是将集合导航属性用于 Any 作为过滤器:

    var studentGrade = context.Grades
        .FirstOrDefault(grade => grade.Students.Any(student => student.Id == studentId));
    

    另一种方法是使用与SQL查询相当的LINQ:

    var studentGrade = (
        from grade in context.Grades
        from student in grade.Students
        where student.Id == studentId
        select grade).FirstOrDefault();
    
        2
  •  1
  •   Kirill Bestemyanov    5 年前

    不能按条件包含导航属性。Include只能包含lambda to导航属性,无任何条件。要解决您的问题,您应该向班级学生添加导航属性“年级”,并从包括年级在内的学生中进行选择。

    public class Student
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
        public Grade StudentGrade { get; set; }
    }
    
    …
    var data = context.Students.Include(x => x.Grade).Where(c => c.Id == studentId).SingleOrDefault();