zoukankan      html  css  js  c++  java
  • EF 使用笔记

    1 事务:一 次性保存全部的变化

    using (JDDbContext context = new JDDbContext())
     {
              context.Database.Log += c => Console.WriteLine(c);
    
              User user2 = context.Users.Find(2);
              user2.Name = user2.Name + "123";
    
             User user7 = context.Users.Find(7);
             user7.Name = user7.Name + "123123123123";
             context.SaveChanges();
        
    }

       2.1  context更新时保存全部变化,不能全局都是一个context

       2.2 不同的context 也不能join的,除非都load到内存之后再去操作
       2.3 context是一个数据库连接+内存对象,资源开销  一次请求,就是一个context,也不排除可能多个;
       2.4更多的时候,是一个service一个context实例,多个请求 /多线程 最好是不同的context

       using (JDDbContext context1 = new JDDbContext())

       using (JDDbContext context2 = new JDDbContext())
      {
            context1.Database.Log += c => Console.WriteLine(c);
            context2.Database.Log += c => Console.WriteLine(c);

              var list = from u in context1.Users
              join c in context2.Categories on u.CompanyId equals c.Id
            into ucList
             from uc in ucList.DefaultIfEmpty()
              where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)
             select new
            {
                  Account = u.Account,
                 Pwd = u.Password
             };
              foreach (var user in list)
             {
                   Console.WriteLine("{0} {1}", user.Account, user.Pwd);
             }
    }

     3 本地缓存   Where查询不缓存;Find先在本地缓存查找(可能脏读,性能好处)

    using (JDDbContext context = new JDDbContext())

    {
         context.Database.Log += c => Console.WriteLine(c);
         var list = context.Users.Where(u => u.Id < 5).ToList();
        Console.WriteLine("*****************0*****************");
        var user1 = context.Users.Find(2);
        Console.WriteLine("*****************1*****************");
        var user2 = context.Users.Where(u => u.Id == 2).ToList();
        Console.WriteLine("*****************2*****************");
        var user3 = context.Users.Find(2);
        Console.WriteLine("*****************3*****************");
        var user4 = context.Users.Where(u => u.Id == 2).ToList();
        Console.WriteLine("*****************4*****************");
    }

    4  本地缓存 AsNoTracking() 表示不跟踪,不在内存做clone(增删改不行,有性能提升)

     using (JDDbContext context = new JDDbContext())
    {
        context.Database.Log += c => Console.WriteLine(c);
        var list1 = context.Users.Where(u => u.Id > 5).AsNoTracking().ToList();
        Console.WriteLine("*****************list1*****************");
        var user1 = context.Users.Find(16);
        Console.WriteLine("*****************1*****************");
        var list2 = context.Users.Where(u => u.Id > 5).ToList();
        Console.WriteLine("******************list2****************");
        var userx = context.Users.Find(16);
        Console.WriteLine("*****************1*****************");
        var list3 = context.Users.Where(u => u.Id > 5).ToList();
        Console.WriteLine("******************list3****************");
        var list4 = context.Users.Where(u => u.Id > 5).ToList();
        Console.WriteLine("*****************list4*****************");
    }

    5  导航属性延迟加载/预先加载/显示加载

    Console.WriteLine("******************************************");
    using (JDDbContext context = new JDDbContext())
    {
        context.Database.Log += c => Console.WriteLine(c);
        var companyList = context.Set<Company>().Where(c => c.Id > 0);
        //var companyList = context.Set<Company>().Where(c => c.Id > 0).ToList();//.ToList()直接Company都加载过来

        foreach (var company in companyList)
        {
            Console.WriteLine("Company id={0} name={1}", company.Id, company.Name);
        }
     }

    //1 延迟加载 每次使用子表时再查询
    //2 放弃子表查询
    //3 Include一次性主从表
    //4 放弃子表查询,又去显示获取某个数据
    //主流选择会去导航,内置的方便;innor join也能完成


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

    using (JDDbContext context = new JDDbContext())
    {
        context.Database.Log += c => Console.WriteLine(c);
        //实体类型包含其它实体类型(POCO类)的属性(也可称为导航属性),且同时满足如下条件即可实列延迟加载,
        //1.该属性的类型必需为public且不能为Sealed;
        //2.属性标记为Virtual
        context.Configuration.LazyLoadingEnabled = true;//默认是true 针对导航属性的
        var companyList = context.Set<Company>().Where(c => c.Id > 0);
        foreach (var company in companyList)
        {
            Console.WriteLine("Company id={0} name={1}", company.Id, company.Name);
            foreach (var item in company.Users)//这个时候才去数据库查询user
            {
                Console.WriteLine("User name={0}", item.Name);
             }
            }
        }

    //不延迟加载,不会再次查询了  
     Console.WriteLine("******************************************");
    using (JDDbContext context = new JDDbContext())
    {
        context.Database.Log += c => Console.WriteLine(c);
        context.Configuration.LazyLoadingEnabled = false
        var companyList = context.Set<Company>().Where(c => c.Id > 0);
        foreach (var company in companyList)
        {
            Console.WriteLine("Company id={0} name={1}", company.Id, company.Name);
            foreach (var item in company.Users)//这个时候才不去数据库查询了,所以用户全是空的了
            {
                Console.WriteLine("User name={0}", item.Name);
            }
        }
    }


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

    //不延迟加载,指定Include,一次性加载出来  
    using (JDDbContext context = new JDDbContext())
    {
        context.Database.Log += c => Console.WriteLine(c);
        //context.Configuration.LazyLoadingEnabled = false;
        var companyList = context.Set<Company>().Include("Users").Where(c => c.Id > 0);
        foreach (var company in companyList)
        {
            Console.WriteLine("Company id={0} name={1}", company.Id, company.Name);
            foreach (var item in company.Users)
            {
                Console.WriteLine("User name={0}", item.Name);
            }
        }
    }


    //LoadProperty 手动加载   放弃子表查询,又去显示获取某个数据

    using (JDDbContext context = new JDDbContext())
    {
        ontext.Database.Log += c => Console.WriteLine(c);
        context.Configuration.LazyLoadingEnabled = false;//不延迟加载,指定Include,一次性加载出来
        var companyList = context.Set<Company>().Where(c => c.Id > 0);
        foreach (var company in companyList)
        {
                Console.WriteLine("Company id={0} name={1}", company.Id, company.Name);
                context.Entry<Company>(company).Collection(c => c.Users).Load();//集合显示加载
                //context.Entry<Company>(company).Reference(c => c.User).Load();//单个属性用
                foreach (var item in company.Users)
                {
                        Console.WriteLine("User name={0}", item.Name);
                }
            }
    }
    6   Linq to  Sql 

       //In 写法

         var list = from u in dbContext.Users
        where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)
        select u;
       

        var list = dbContext.Users.Where(u => new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)).OrderBy(u => u.Id)
        .Select(u => new
        {
            Account = u.Account,
            Pwd = u.Password
        }).Skip(3).Take(5);  

       //like  写法  
        var list = dbContext.Users.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);  

      //inner join   写法    
        var list = from u in dbContext.Users
        join c in dbContext.Companies on u.CompanyId equals c.Id
        where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)
        select new
        {
                Account = u.Account,
                Pwd = u.Password,
                CompanyName = c.Name
        };

        //left join   写法      
        var list = from u in dbContext.Users
        oin c in dbContext.Categories on u.CompanyId equals c.Id
        into ucList
        from uc in ucList.DefaultIfEmpty()
        where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)
        select new
        {
            Account = u.Account,
            Pwd = u.Password
        };

        //事务  写法        
      using (JDDbContext dbContext = new JDDbContext())

      {
            DbContextTransaction trans = null;
            try
            {
                trans = dbContext.Database.BeginTransaction();
                string sql = "Update [User] Set Name='小新' WHERE Id=@Id";
                SqlParameter parameter = new SqlParameter("@Id", 1);
                dbContext.Database.ExecuteSqlCommand(sql, parameter);
                trans.Commit();
            }
            catch (Exception ex)
            {
                if (trans != null)
                trans.Rollback();
                 throw ex;
            }
            finally
            {
                trans.Dispose();
            }
        }

             //SQL  写法        
            DbContextTransaction trans = null;
            try
            {
                trans = dbContext.Database.BeginTransaction();
                string sql = "SELECT * FROM [User] WHERE Id=@Id";
                SqlParameter parameter = new SqlParameter("@Id", 1);
                List<User> userList = dbContext.Database.SqlQuery<User>(sql, parameter).ToList<User>();
                trans.Commit();
            }
            catch (Exception ex)
            {
                if (trans != null)
                trans.Rollback();
                throw ex;
            }
            finally
            {
                    trans.Dispose();
            }
        }

    7  其他

      using (JDDbContext context = new JDDbContext())
    {
            context.Database.Log += c => Console.WriteLine($"sql:{c}");
             context.Users.Add(userNew);
            context.SaveChanges();//id自动赋值
            userNew.Name += "1";
            context.SaveChanges();//更新 删除都没问题
    }


    //context实例会跟踪数据(插入/查询) 修改过就会有个状态变化
    using (JDDbContext context = new JDDbContext())
    {
            context.Database.Log += c => Console.WriteLine($"sql:{c}");
            context.Users.Attach(userNew);//直接保存无效 Attach一下,附加之后就可以监控
            userNew.Name += "2";
            context.SaveChanges();
    }


    using (JDDbContext context = new JDDbContext())
    {
            context.Database.Log += c => Console.WriteLine($"sql:{c}");
            userNew = context.Users.Find(userNew.Id);
            userNew.Name += "3";
            context.SaveChanges();
    }


    using (JDDbContext context = new JDDbContext())
    {
            context.Database.Log += c => Console.WriteLine($"sql:{c}");
            userNew.Name += "2";
            context.Users.Attach(userNew);//直接保存无效 Attach一下,附加之后就可以监控
            //context.Entry<User>(userNew).State = EntityState.Modified;
            //告诉context数据改了
            context.Entry<User>(userNew).Property<string>("Name").IsModified = true;
            //告诉context说 name属性更改了
            context.SaveChanges();
    }


    //按需更新:DTO对象--Find---赋值--save;传递json--解析json
    {
            //Update A Set Name=1 Where Name like ''
            //EF不支持, 要么直接sql;要么表达式目录树解析sql 然后执行sql;
    }

  • 相关阅读:
    动态Webapi参考资料
    解决异步事务好文章
    .net core 插件开发
    端口被占用代码
    性能测试
    .NET/.NET Core 单元测试:Specflow
    Autofac 替换默认控制器骚操作
    Swagger非常好的文章
    sqlserver入门到精通(2016安装教程)
    springboot 学习之路 27(实现ip白名单功能)
  • 原文地址:https://www.cnblogs.com/shiding/p/13549322.html
Copyright © 2011-2022 走看看