• 泛型委托与单独lambda查询异同


      前两天为OA系统添加了登录日志,登录类型分三类:工业园IP登录、同步IP登录、短信验证码登录,写日志之前先判断用户账号是否存在是否允许登录继而是否是合法IP地址继而密码是否正确,如果是非工业园IP登录判断其短信验证码是否正确,以上验证都通过才写入日志记session,  测试正常即发布。上线后研究登录日志数据发现了奇怪的数据:类型为短信验证码登录但是并没有其他用户信息,而我在登录成功后都会记录登录账号、工号、时间、IP、登录结果等信息,断点调试代码也没有发现问题。遂在写日志的时候又加了层验证用户账号和密码如果不成功返回“Warning,非法登录请自行离去”,今早发布后终于有同事反馈OA无法登录并截图发给我,我发现他的登录账号含有大写字母而我们数据库中所有账号皆是小写,遂用该账号测试登录,果真发现问题根源……

      先介绍下OA系统架构方面,我们使用MVC5+EF+Mysql,在底层封装了返回实体方法:   

      public IQueryable<T> LoadEntities(Func<T, bool> whereLambda)
      {
            return dbContext.Set<T>().Where<T>(whereLambda).AsQueryable();
      }
    

      问题就出在这个泛型委托参数whereLambda(不要问我为什么不用表达式查询,因为调用该方法的地方实在太多了……而且很多地方都用了类型转换), 而我新增的验证用户方法确实调用了该方法

    hr_employee emp = emp_biz.LoadEntities(t => t.uid == model.UserID && t.pwd == pwd).FirstOrDefault();(注:pwd是经过加密的),当使用大写的账号登录时emp为null,而我在写日志之前的判断用户是否存在和密码是否正确时用的是直接linq查询hr_employee   emp = dbContext.hr_employee.Where(t => t.uid == uid).FirstOrDefault(); 啰里啰嗦到写到现在相信大家都发现了问题根源,也一定知道为何如此,但是不是像我一样不大确定呢,那我们就用事实说话。我的猜想:问题就出在泛型委托上,它本身就是个方法,“==”对等条件就是两边必须一致才返回true,而单纯的linq where 查询就是sql语句。下面验证猜想。

          1.Func<T,bool>

           public ActionResult Index()
            {
                List<test23> list = new List<test23>();
                list = LoadEntities(t =>t.name=="sean").ToList();
    
                return View(list);
            }
    
            public IQueryable<test23> LoadEntities(Func<test23, bool> whereLambda)
            {
                OAEntities dbContext = new OAEntities();
                return dbContext.Set<test23>().Where<test23>(whereLambda).AsQueryable();
            }
    

     前台输出: 

        2.linq查询     

           public ActionResult Index()
            {
                List<test23> list = new List<test23>();
                using (OAEntities dbcontext = new OAEntities())
                {
                    list = dbcontext.test23.Where(t => t.name == "sean").ToList();
                }
    
                //list = LoadEntities(t =>t.name=="sean").ToList();
    
                return View(list);
            }
    

     前台输出:

       由此证明猜想。 

    学无先后,达者为师
  • 相关阅读:
    Android中的内部类引起的内存泄露
    Android的消息机制: Message/MessageQueue/Handler/Looper
    ArrayList/Vector的原理、线程安全和迭代Fail-Fast
    JVM中的Stack和Frame
    JVM中的垃圾收集算法和Heap分区简记
    无锁编程以及CAS
    简述Java内存模型的由来、概念及语义
    MQTT协议简记
    RabbitMQ的工作队列和路由
    RabbitMQ 入门
  • 原文地址:https://www.cnblogs.com/seanchang/p/8328658.html
Copyright © 2020-2023  润新知