• 学习LINQ to SQL查询


    join,left join

            static void Main(string[] args)
            {
                var db = new dbEntities();
                var query = from s in db.Store
                            join o in db.Organization on s.OrgId equals o.OrgId
                            join o2 in db.Organization on o.ParentId equals o2.OrgId //自连接
                            join f in db.Tbl_FenZu on s.StoreId equals f.StoreId into f0
                            from f in f0.DefaultIfEmpty() //LEFT OUTER JOIN
                            join k in db.Tbl_KaZuo on f.Id equals k.FenZuId into k0
                            from k in k0.DefaultIfEmpty()
                            where s.InsertTime > new DateTime(2018, 1, 1)
                            orderby o2.OrgId, o.OrgId, s.StoreId, f.Id, k.Id
                            select new { 省 = o2.OrgName, 市 = o.OrgName, s.StoreId, s.StoreCode, s.FullName, f.Name, k.Code };
                var dt = ToDataTable(query.ToList());
            }

    group,having,聚合

                var query = from s in db.Store
                            join f in db.Tbl_FenZu on s.StoreId equals f.StoreId into f0
                            from f in f0.DefaultIfEmpty()
                            group f by new { s.StoreId, s.FullName } into g
                            where g.Count() > 1
                            orderby g.Key.StoreId
                            select new { ID = g.Key.StoreId, Name = g.Key.FullName, FzCount = g.Count() };

     当前sqlserver版本没有原生字符串聚合函数的问题

    之前都是直接使用sql语句可以使用 for xml path 或者用C#给sqlserver写自定义聚合函数

    而现在想用 EF 就遇到了问题,LINQ to Entities 不识别方法。。。linq无法翻译成sql

                //var query = from s in db.Store
                //            join f in db.Tbl_FenZu on s.StoreId equals f.StoreId into f0
                //            from f in f0.DefaultIfEmpty()
                //            group f by new { s.StoreId, s.FullName } into g
                //            where g.Count() > 1
                //            orderby g.Key.StoreId
                //            //select new { ID = g.Key.StoreId, Name = g.Key.FullName, FzCount = g.Count(), aa = g.Select(d => d.Name).Aggregate((a, b) => $"{a},{b}") }; //LINQ to Entities 不识别方法 System.String Aggregate
                //            select new { ID = g.Key.StoreId, Name = g.Key.FullName, FzCount = g.Count(), aa = string.Join(",", g.Select(d => d.Name)) }; // LINQ to Entities 不识别方法 System.String Join

    只能换个思路

                var query = from s in db.Store
                            join f in db.Tbl_FenZu on s.StoreId equals f.StoreId into f0
                            from f in f0.DefaultIfEmpty()
                            group f by new { s.StoreId, s.FullName } into g
                            where g.Count() > 1
                            orderby g.Key.StoreId
                            select new { ID = g.Key.StoreId, Name = g.Key.FullName, FzCount = g.Count(), Fz = g }; //生成的sql很大很傻,实际上也没有分组。没必要这样写
    
                var lst = query.ToList();
                //这种思路:先查询出sql数据,再用LINQ to Object来处理“字符串聚合”
                var lst00 = lst.Select(d => new { d.ID, d.Name, d.FzCount, Fz = d.Fz.Select(o => o.Name).Aggregate((a, b) => $"{a},{b}") }).ToList();
    
                var dt = ToDataTable(lst);
                var dt00 = ToDataTable(lst00);

      目的达到了:

      但是 这个 linq 语句可不怎么好(生成的sql很大很傻,实际上也没有分组。没必要这样写),改进下

                var query = from s in db.Store
                            join f in db.Tbl_FenZu on s.StoreId equals f.StoreId 
                            select new { ID = s.StoreId, Name = s.FullName, Fz = f.Name };
                //先让sql生成
                var lst = query.ToList();
                //再加工数据
                var lst_g = lst.GroupBy(d => d.ID).Select(g=>new {ID= g.Key,Name=g.First().Name, FzCount = g.Count(), Fz =g.Select(d=>d.Fz).Aggregate((a, b) => $"{a},{b}") }).ToList();
                var dt = ToDataTable(lst_g);

     以前公司的表动不动就是上千万甚至上亿行,未分组的原始数据的量非常大的情况下也可以用EF执行直接sql

    以前公司使用ado.net配合sqlhelper多个查询条件经常会字符串动态拼sql,linq如何实现呢,园子里逛了逛主流的有这几种:

    1.使用 Expression表达式,动态构造,有点高端,不是很熟悉这些高级东西,主要是各种委托参数

    2.直接拼linq语句,还是这个好理解哈

    var search = from User u in myDataCcontext.User select u;
    if(name!=null && name!=string.Empty)
        search=search.Where(u=>u.姓名==name);
    if(addr!=null && addr!=string.Empty)
        search=search.Where(u=>u.住址.StartsWith(Addr));

    一个常见的查询写法

     1         public JsonResult GetList(int offset, int limit, string order = null, string sort = null, string search = null, int? filteClass = null, string status = null, string graduationType = null,bool Completed=false)
     2         {
     3             var orderDirection = string.IsNullOrEmpty(order) || order.ToLower().Equals("asc") ? Extend.OrderDirection.ASC : Extend.OrderDirection.DESC;
     4 
     5             var logIdExpression = from log in Db_OA.Censu_Logs
     6                                   group log by log.CensuID into logCollection
     7                                   select logCollection.Max(p => p.ID);
     8             var logExpression = from log in Db_OA.Censu_Logs
     9                                 join logId in logIdExpression on log.ID equals logId
    10                                 select log;
    11             var queryExpression = from censu in Db_OA.Censu_Census
    12                                   join log in logExpression on censu.ID equals log.CensuID
    13                                   join udwFilter in Db_OA.Human_UDW on censu.NetID equals udwFilter.NETID into udwCollection
    14                                   from udw in udwCollection.DefaultIfEmpty()
    15                                   join enclosureFilter in Db_OA.Enclosure_Enclosures on censu.Permit equals enclosureFilter.ID into enclosureCollection
    16                                   from enclosure in enclosureCollection.DefaultIfEmpty()
    17                                   select new
    18                                   {
    19                                       censu.ID,
    20                                       censu.NetID,
    21                                       udw.FirstName,
    22                                       udw.LastName,
    23                                       censu.Name,
    24                                       censu.Class,
    25                                       Permit = enclosure.RelativePath,
    26                                       censu.Remark,
    27                                       censu.UpdateTime,
    28                                       censu.RelocationAddress,
    29                                       censu.RelocationRemark,
    30                                       censu.RelocationType,
    31                                       log.Status,
    32                                       LogTime = log.UpdateTime,
    33                                       log.UpdateBy,
    34                                       censu.AccountType,
    35                                       censu.NativePlace,
    36                                       censu.IDNumber,
    37                                       censu.Contact
    38                                   };
    39             queryExpression = queryExpression
    40                 .WhereIF(!string.IsNullOrEmpty(search), p => p.NetID.Contains(search) || p.FirstName.Contains(search) || p.LastName.Contains(search) || p.Status.Contains(search) || p.RelocationAddress.Contains(search))
    41                 .WhereIF(!string.IsNullOrEmpty(status), p => p.Status.Equals(status))
    42                 .WhereIF(!string.IsNullOrEmpty(graduationType), p => p.RelocationType.Equals(graduationType))
    43                 .WhereIF(filteClass != null, p => p.Class.Equals(filteClass.Value))
    44                 .WhereIF(Completed, p => p.Status == "Received")
    45                 .WhereIF(!Completed, p => p.Status != "Received")
    46                 .OrderByIF(string.IsNullOrEmpty(sort), p => p.LogTime, Extend.OrderDirection.DESC)
    47                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("NetID"), p => p.NetID, orderDirection)
    48                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("FirstName"), p => p.FirstName, orderDirection)
    49                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("Class"), p => p.Class, orderDirection)
    50                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("UpdateTime"), p => p.UpdateTime, orderDirection)
    51                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("Status"), p => p.Status, orderDirection)
    52                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("RelocationAddress"), p => p.RelocationAddress, orderDirection)
    53                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("RelocationType"), p => p.RelocationType, orderDirection)
    54                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("UpdateBy"), p => p.UpdateBy, orderDirection)
    55                 .OrderByIF(!string.IsNullOrEmpty(sort) && sort.Equals("LogTime"), p => p.LogTime, orderDirection);
    56 
    57             var total = queryExpression.AsNoTracking().Select(p => p.ID).Count();
    58 
    59             queryExpression = queryExpression.OrderByIF(string.IsNullOrEmpty(sort), p => p.UpdateTime, Extend.OrderDirection.DESC);
    60 
    61             var rows = queryExpression.AsNoTracking().Skip(offset).Take(limit).ToList();
    62 
    63             return Print_Message(new { rows, total });
    64         }
    View Code

    事务

     1             var transaction = Db_OA.Database.BeginTransaction();
     2             try
     3             {
     4                 ...
     5 
     6                 db.SaveChanges();
     7 
     8                 transaction.Commit();
     9 
    10                 return resSuccess();
    11             }
    12             catch (Exception ex)
    13             {
    14                 transaction.Rollback();
    15                 ...
    16                 return resError(ex.InnerException?.Message ?? ex.Message);
    17             }
    View Code
  • 相关阅读:
    第七章 内部类与异常类
    2019 Multi-University Training Contest 1
    2019 Multi-University Training Contest 4
    支配树总结
    2019牛客多校第四场题解
    2019牛客多校第三场题解
    莫比乌斯函数总结
    2019牛客多校训练第二场题解
    2019牛客多校训练第一场题解
    洛谷P3069 [USACO13JAN]牛的阵容Cow Lineup(尺取法)
  • 原文地址:https://www.cnblogs.com/mmclog/p/14142859.html
Copyright © 2020-2023  润新知