zoukankan      html  css  js  c++  java
  • EntityFramework之原始查询如何查询未映射的值,你又知道多少?

    前言

    今天又倒腾了下EF,如题所示,遇到了一些问题,并最终通过尝试找到了解决方案,可能不是最终的解决方案,若你有更好的解决方案,望告知,同时通过阅读此文,定让你收获不少。

    引入 

    当我们查询时一直是中规中矩的查询,当然,这并没有错,那是对实体的字段未加以限制,或者说是你项目中没有此业务。当映射我们将实体中的某些字段进行忽略,但是当查询时我们又需要查询忽略的字段,还没听懂?说的通俗一点就是:在项目中这样的需求肯定是存在的,我们实体中添加的属性,可能是通过其他实体映射到表而关联出来,此时我们完全不需要映射此实体的字段。下面我们来进行演示,一看便知。

    演示

    首先我们给出两个实体,学生类Student,以及小红花类Flower

        public class Student
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public int FlowerId { get; set; }
    
            public string FlowerRemark { get; set; } //此属性需要关联Flower类而获取,我们将其标记为不进行映射
    
           
        }
    
    
        public class Flower
        {
            public int Id { get; set; }
    
            public string FlowerRemark { get; set; }
    
        }

    映射类

        public class FlowerMap : EntityTypeConfiguration<Flower>
        {
            public FlowerMap()
            {
                ToTable("Flower");
                HasKey(p => p.Id);
            }
        }
    
        public class StudentMap : EntityTypeConfiguration<Student>
        {
            public StudentMap()
            {
                ToTable("Student");
                HasKey(key => key.Id);
                Property(p => p.Id);
                Ignore(p => p.FlowerRemark);
            }
    
        }

    现在我们需要以Student类中FlowerId和Flower类中Id相等来获得学生类中FlowerRemark值。

     var result = ctx.Database.SqlQuery<Student>("select S.Id, S.FlowerId, S.Name, F.FlowerRemark from Student S  join Flower F on S.FlowerId = F.Id").ToList();

    我们来看看其结果

    是不是有点令你始料未及,其实仔细想想也对,从此我们可以得出如下结论:

    若将属性标记为忽略映射此字段,当查询时将检测到此属性的标记为忽略所以此时也将忽略对此字段的查询,那么当然查询其结果将为null

    既然问题已经暴露出来了,那来吧,我们就解决吧!

    解决方案

    • 第一步

    既然是检测到此标记为忽略映射此字段,此时我们就将再定义一个类,用于转换的类即可,如下:

        public class StudentViewModel
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public int FlowerId { get; set; }
    
            public string FlowerRemark { get; set; }
        }
    •  最后一步

    接下来查询时将返回的类型为 StudentViewModel 即可,而不再是Student。

    var result = ctx.Database.SqlQuery<StudentViewModel>("select S.Id, S.FlowerId, S.Name, F.FlowerRemark from Student S  join Flower F on S.FlowerId = F.Id").ToList();

    我们再来看看其结果,成功解决

    当然此时你若只是查询返回的当然肯定是Student的集合列表而非转换后的StudentViewModel,此时进行如下修改即可:

                    var result = ctx.Database.SqlQuery<StudentViewModel>("select S.Id, S.FlowerId, S.Name, F.FlowerRemark from Student S  join Flower F on S.FlowerId = F.Id").ToList()
                        .Select(stu => new Student()
                    {
                        Id = stu.Id,
                        FlowerId=stu.FlowerId,
                        Name = stu.Name,
                        FlowerRemark = stu.FlowerRemark
                    }).ToList();

    至此完美,结束。

    总结

    当用原始查询查询未映射到数据库表中的字段(因为此属性只是关联其他表而来,所以无需对其进行映射)时,查询其结果将为null,此时需要转换思路,即需要通过上述稍许转换即可达到我们目的。

  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/4862593.html
Copyright © 2011-2022 走看看