IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> EntityFramework6(二) -> 正文阅读

[大数据]EntityFramework6(二)

Linq查询

无论是什么查询----一定是生成Sql语句;数据库只认识Sql语句;
如何查看Sql语句:
1.SqlProfiler,可以监听到数据库执行的所有SQL语句
2.通过EF6日志打印数据Sql语句

            using (SunDbContext dbContext = new SunDbContext())
            {
				//输出ef6的日志
                dbContext.Database.Log += s => Console.WriteLine($"sql:{s}");
                //dbContext.Database.Log += c => Console.WriteLine($"sql:{c}");
                {
                    //无论是什么查询----一定是生成Sql语句;数据库只认识Sql语句;
                    //如何查看Sql语句
                    //1.SqlProfiler,可以监听到数据库执行的所有SQL语句
                    //2.通过EF6日志打印数据Sql语句
                    var idlist = new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17 };//in查询 
                    var list = dbContext.SysUsers.Where(u => idlist.Contains(u.Id));//in查询
                    foreach (var user in list)
                    {
                        Console.WriteLine(user.Name);
                    }
                }
                {
                    //没有任何差别,只有写法上的熟悉
                    var list = from u in dbContext.SysUsers
                               where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)
                               select u;

                    foreach (var user in list)
                    {
                        Console.WriteLine(user.Name);
                    }
                }
                {
                    var list = dbContext.SysUsers.Where(u => new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 18, 19, 20, 21, 22, 23 }.Contains(u.Id))
                                              .OrderBy(u => u.Id)
                                              .Select(u => new
                                              {
                                                  Name = u.Name,
                                                  Pwd = u.Password
                                              }).Skip(3).Take(5);
                    foreach (var user in list)
                    {
                        Console.WriteLine(user.Pwd);
                    }
                }
                {
                    var list = (from u in dbContext.SysUsers
                                where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)
                                orderby u.Id
                                select new
                                {
                                    Name = u.Name,
                                    Pwd = u.Password
                                }).Skip(3).Take(5);

                    foreach (var user in list)
                    {
                        Console.WriteLine(user.Name);
                    }
                }

                {
                    var list = dbContext.SysUsers.Where(u => u.Name.StartsWith("小")
                                               && u.Name.EndsWith("村长"))
                                               .Where(u => u.Name.EndsWith("长"))
                                               .Where(u => u.Name.Contains("名村"))
                                               .Where(u => u.Name.Length < 5)
                                               .OrderBy(u => u.Id);

                    foreach (var user in list)
                    {
                        Console.WriteLine(user.Name);
                    }

                    var list1 = from u in dbContext.SysUsers
                                where u.Name.StartsWith("小")
                                 && u.Name.EndsWith("村长")
                                where u.Name.EndsWith("长")
                                select new { Name = u.Name, pwd = u.Password };

                    foreach (var user in list1)
                    {
                        Console.WriteLine(user.Name);
                    }
                }
                {

                    //dbContext.SysUsers.Join() 
                    var list = (from u in dbContext.SysUsers
                               join c in dbContext.Companies on u.CompanyId equals c.Id //条件不能写等号,要使用equals关键字
                               where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)
                               select new
                               {
                                   Name = u.Name,
                                   Pwd = u.Password,
                                   CompanyName = c.Name
                               }).OrderBy(u=>u.CompanyName).Skip(3).Take(5);

                    foreach (var user in list)
                    {
                        Console.WriteLine("{0} {1}", user.Name, user.Pwd);
                    }
                }
            }

SQL查询

那都是生成Sql语句,如果我自己来一条Sql语句呢?咋玩?
dbContext.Database.SqlQuery< SysUser>(sql, parameter)

事务执行:
dbContext.Database.BeginTransaction()
trans.Commit()

            //如果遇到非常复杂的查询----建议直接写Sql语句;
            using (SunDbContext dbContext = new SunDbContext())
            {
                {
                    DbContextTransaction trans = null;
                    try
                    {
                        trans = dbContext.Database.BeginTransaction();//开启一个事务
                        string sql = "Update [SysUser] Set Name='小新' WHERE Id=@Id";
                        SqlParameter parameter = new SqlParameter("@Id", 3);
                        dbContext.Database.ExecuteSqlCommand(sql, parameter);
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        if (trans != null)
                            trans.Rollback();
                        throw ex;
                    }
                    finally
                    {
                        trans.Dispose();
                    }
                }
                {
                    DbContextTransaction trans = null;
                    try
                    {
                        trans = dbContext.Database.BeginTransaction();
                        string sql = "SELECT * FROM [SysUser] WHERE Id=@Id";
                        SqlParameter parameter = new SqlParameter("@Id", 3); 
                        //var query= dbContext.Database.SqlQuery(); 
                        List<SysUser> userList = dbContext.Database.SqlQuery<SysUser>(sql, parameter).ToList<SysUser>();
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        if (trans != null)
                            trans.Rollback();
                        throw ex;
                    }
                    finally
                    {
                        trans.Dispose();
                    }
                }
            }

EntityState状态跟踪

一次SaveChanges 就把在Context中的所有操作都提交到数据库中去了;
SaveChange就是以Context为维度的;
要提交到数据库中的对象和Context一定存在某种关系;----就是对象是否给Context跟踪;状态;

            //EntityState
            using (SunDbContext context = new SunDbContext())
            {
                SysUser userNew = new SysUser()
                {
                    Name = "7z",
                    Password = "12356789",
                    Status = 1,
                    Phone = "18672713698",
                    Mobile = "18664876671",
                    Address = "xxx市",
                    Email = "18672713698@qq.com",
                    QQ = 75379953,
                    WeChat = "xxxx",
                    Sex = 1,
                    CreateTime = DateTime.Now,
                    CompanyId = 4,
                    LastLoginTime = null,
                    LastModifyTime = DateTime.Now
                };

                Company company = new Company()
                {
                    Name = "腾讯有限公司",
                    LastModifierId = 1,
                    CreateTime = DateTime.Now,
                    CreatorId = 1,
                    LastModifyTime = DateTime.Now
                };
                context.Companies.Add(company);
                //新增
                context.SysUsers.Add(userNew);
                context.SaveChanges();
                //修改
                userNew.Name = "天气老师";
                context.SaveChanges(); //为什么这里的对象属性修改,SaveChanges 以后也能够提交到数据库中去呢?
                //删除
                context.SysUsers.Remove(userNew);
                context.SaveChanges();
            }

在这里插入图片描述
Context.Entry< User>(userNew).State :获取实体的状态

Detached: 和Context 完全没有任何关系,不受Context跟踪
Unchanged:受Context跟踪,但是没有做任何操作
Added:受Context 跟踪,SaveChange就添加到数据库
Deleted:受Context跟踪,SaveChange就删除数据库数据
Modified:受Context跟踪,SaveChange就修改数据库

                SysUser userNew = new SysUser()
                {
                    Name = "7z",
                    Password = "12356789",
                    Status = 1,
                    Phone = "18672713698",
                    Mobile = "18664876671",
                    Address = "xxx市",
                    Email = "18672713698@qq.com",
                    QQ = 75379953,
                    WeChat = "xxxx",
                    Sex = 1,
                    CreateTime = DateTime.Now,
                    CompanyId = 4,
                    LastLoginTime = null,
                    LastModifyTime = DateTime.Now
                };

                //EF为为了做增删改---EntityState
                //能够修改多个状态统一提交吗?----需要让Context跟踪对象;
                using (SunDbContext context = new SunDbContext())
                {
                    Console.WriteLine(context.Entry<SysUser>(userNew).State); //Detached 二者没啥关系,就是SaveChange也啥也不干;
                    userNew.Name += "abcd";
                    Console.WriteLine(context.Entry<SysUser>(userNew).State); //Detached 二者没啥关系,就是

                    Console.WriteLine("*******************************************");

                    //新增
                    context.SysUsers.Add(userNew); 
                    Console.WriteLine(context.Entry<SysUser>(userNew).State); //Added  新增
                    Console.WriteLine("*******************************************");
                    context.SaveChanges();
                    Console.WriteLine(context.Entry<SysUser>(userNew).State);  //Unchanged  被Context跟踪
                    Console.WriteLine("*******************************************");
                    //修改
                    userNew.Name = "小星星老师";
                    Console.WriteLine(context.Entry<SysUser>(userNew).State);  //Modified
                    Console.WriteLine("*******************************************");
                    context.SaveChanges(); //为什么这里的对象属性修改,SaveChanges 以后也能够提交到数据库中去呢? 
                    Console.WriteLine(context.Entry<SysUser>(userNew).State); //Unchanged
                    Console.WriteLine("*******************************************");
                    //删除
                    context.SysUsers.Remove(userNew);
                    Console.WriteLine(context.Entry<SysUser>(userNew).State);//Deleted
                    Console.WriteLine("*******************************************");
                    context.SaveChanges();
                    Console.WriteLine(context.Entry<SysUser>(userNew).State);//删除不仅删除数据库,在内存也移除;Detached
                    Console.WriteLine("*******************************************");
                }
            }

SaveChanges是以context为维度,如果监听到任何数据的变化;然后会一次性的保存到数据库去,而且会开启事务!

那如果是这样的话,岂不是每一次更新都需要从数据库里查询一次?
大部分情况下是这样,先查询,再修改,为了保证实体受Context监管!
也可以有其他的方案:Context.实体名称.Attach() 接受Context监管!

            SysUser userNew1 = new SysUser()
            {
                    Name = "ABCDEFG",
                    Password = "12356789",
                    Status = 1,
                    Phone = "18672713698",
                    Mobile = "18664876671",
                    Address = "xxx市",
                    Email = "18672713698@qq.com",
                    QQ = 75379953,
                    WeChat = "xxxx",
                    Sex = 1,
                    CreateTime = DateTime.Now,
                    CompanyId = 4,
                    LastLoginTime = null,
                    LastModifyTime = DateTime.Now
            };

            //EF为为了做增删改---EntityState
            //能够修改多个状态统一提交吗?----需要让Context跟踪对象;
            using (SunDbContext context = new SunDbContext())
            {
                context.SysUsers.Attach(userNew1);
                Console.WriteLine(context.Entry<SysUser>(userNew1).State);
                context.SaveChanges();
                Console.WriteLine(context.Entry<SysUser>(userNew1).State);
                userNew1.Name += "123465";
                context.SaveChanges(); //会抛异常,因为数据库中并不存在该条数据,主键在数据库中不存在
                Console.WriteLine(context.Entry<SysUser>(userNew1).State);
            }
            SysUser sysUser2 = null;
            //2.调用Attach 方法的时候,如果让Context跟踪+一些数据操作,必须保证数据的主键和数据库要一致;
            using (SunDbContext context = new SunDbContext())
            {
                SysUser user = context.SysUsers.Find(100026);
                Console.WriteLine(context.Entry<SysUser>(user).State);
                sysUser2 = user.clone();//此处为深克隆,sysUser2的主键在数据库中存在
                Console.WriteLine(context.Entry<SysUser>(sysUser2).State);

                context.SysUsers.Attach(sysUser2);//Context跟踪到了sysUser2对象
                Console.WriteLine(context.Entry<SysUser>(sysUser2).State);
                sysUser2.Name += "123456987";
                Console.WriteLine(context.Entry<SysUser>(sysUser2).State);
                context.SaveChanges();
                //userNew1.Name += "123465";
                //context.SaveChanges();
                //Console.WriteLine(context.Entry<SysUser>(userNew1).State);
            }

状态跟踪有成本:在内存中Clone一个对象,只要是被Context跟踪上的;每一次修改,都会和内存中的克隆的对象做比较;比较之后的结果就是新状态;—也会影响我们的性能;

取消对象的状态跟踪:AsNoTracking() 方法会直接切断Context跟踪;可以提高性能!

            {
                using (SunDbContext context = new SunDbContext())
                {
                    SysUser user = context.SysUsers.Find(100026);
                    Console.WriteLine(context.Entry<SysUser>(user).State); //Unchanged,被跟踪需要资源开销 
                                                                           //如果查询数据后:不需要修改;
                    var user1 = context.SysUsers.AsNoTracking().FirstOrDefault(u => u.Id == 100026);//没有给Context跟踪,就没有在内存中Clone对象,会提高性能;
                    Console.WriteLine(context.Entry<SysUser>(user1).State);
                    var userQuery = context.SysUsers.Where(u => u.Id == 100026).ToList();
                    Console.WriteLine(context.Entry<SysUser>(userQuery.First()).State);
                }
            }

EF中的缓存提升效率:
Find查询默认是优先从内存中去查找,如果内存没有,就再去数据库查找,可以提高性能;
建议:大家尽量的使用Find查询

            //缓存 ---在同一个Context
            {
                using (SunDbContext context = new SunDbContext())
                {
                    var userlist = context.SysUsers.Where(u => u.Id > 100025).ToList();
                    Console.WriteLine("*******************************************************");
                    SysUser user = context.SysUsers.Find(100026);//EF6中会有缓存,Find查询的时候,会优先去查看内存;如果内存中已经存在,就不再去数据库查询,否则再去数据库查询;
                    //Linq每一次都是需要去数据库做查询----建议大家尽量使用Find
                    Console.WriteLine("*******************************************************");
                    SysUser user1 = context.SysUsers.FirstOrDefault(u => u.Id == 100026);
                }

                using (SunDbContext context = new SunDbContext())
                {
                    SysUser user = context.SysUsers.Find(100026);

                }
            }

那如何更新全部字段0呢?
context.Entry< User>(user).State = EntityState.Modified;//全字段更新
那如何选择性的更新字段呢?
context.Entry< User>(user5).Property(“Name”).IsModified = true;

            SysUser updateuser = null;
            //按需更新; 
            using (SunDbContextcontext = new SunDbContext())
            {
                SysUser user = context.SysUsers.Find(100026);
                user.Name = "tengxunketang";
                context.SaveChanges();//只会更新Name字段; 
                
                //1.先查询在赋值修改 
                var upUser = context.SysUsers.Find(updateuser.Id);
                //upUser 赋值

                //2. .Property("Name").IsModified = true
                //3.传递一个Json字符串  Key--Value  key--字段名称   value--值,判断哪些是需要修改的,就赋值修改哪些 
                context.Entry<SysUser>(updateuser).State = EntityState.Modified;//修改所有属性;
                context.Entry<SysUser>(updateuser).Property("Name").IsModified = true;//只修改当前字段 
            }

多个新增、修改 savechange()相当于是在同一个事务中进行,某一条语句失败事务就无法提交。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:21:27  更:2021-09-29 10:22:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 0:45:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码