从LINQ开始之LINQ to Objects(上)

LINQ概述


  LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源。

1.LINQ体系结构

从上图可以看出,LINQ总共包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。

LINQ to Objects:对内存中集合的操作

LINQ to DataSets:对数据集Datatable的操作

LINQ to SQL:对SQL Server数据源的操作,微软把开发的重点从LINQ to SQL转移到了LINQ to Entities并且宣布LINQ to SQL不再提供更新

LINQ to Entities:是 Entity Framework的一部分并且取代LINQ to SQL作为在数据库上使用 LINQ的标准机制

LINQ to XML:对XML数据源的操作

2.LINQ的语法

  下面是一个简单的示例,查询一个int数组中小于5的元素,并按照从小到大的顺序排列:

int[] arr = new int[] { 1, 4, 2, 6, 7, 9, 5, 1, 2, 4 }; var query = from r in arr        
           where r < 5orderby r  
             select r;  
     foreach (var item in query){Console.WriteLine(item);}Console.ReadLine();

  由此示例可以看出:LINQ查询表达式以from子句开头,以select子句结束。在两个子句之间,可以使用where、orderby等查询操作符。

  LINQ有两种语法:Lambda语法和Query语法,编译器会在程序编译时转换LINQ查询,以调用相应的扩展方法。

以下是LINQ表达式结构示意图:

引用自百度百科

LINQ to Objects


LINQ to Objects中的扩展方法在System.Core程序集的System.Linq命名空间中定义。

1.Enumerable类定义的标准查询操作符:

下面介绍使用这些操作符的示例:

首先,我们需要创建基本的实体类Employee:


/// <summary>

/// 员工类

/// </summary>

public class Employee

{

    //员工编号

    public string EmployeeId { get; private set; }

    //员工姓名

    public string EmployeeName { get; private set; }

    //年龄

    public int Age { get; private set; }

    //入职日期

    public DateTime EntryDate { get; private set; }

    //性别

    public string Sex { get; private set; }

    //部门

    public string Department { get; private set; }

    //薪水

    public int Salary { get; private set; }

    //爱好

    public IEnumerable<string> Hobby { get; private set; }


     public Employee(string employeeId, string employeeName, int age, DateTime entryDate, Sex sex, Department department, int salary, IEnumerable<string> hobby)

    {

        this.EmployeeId = employeeId;

        this.EmployeeName = employeeName;

        this.Age = age;

        this.EntryDate = entryDate;

        this.Sex = sex.ToString();

        this.Department = department.ToString();

        this.Salary = salary;

        this.Hobby = hobby;

    }

}


//性别

public enum Sex

{

    Male,

    Female

}


//部门

public enum Department

{

    HR,

    IT,

    PD,

    FD,

    QC,

    MD

}


然后,创建列表employees保存10名员工的基本信息:

 List<Employee> employees = new List<Employee>()

{

    new Employee("001","Mike",32,new DateTime(2016,2,20),Sex.Male,Department.IT,200000,new string[] { "swimming","shopping"}),

    new Employee("002","Jack",38,new DateTime(2007,5,12),Sex.Male,Department.HR,409989,new string[] { "reading"}),

    new Employee("003","Adolph",25,new DateTime(2017,3,23),Sex.Male,Department.IT,100000,new string[] { "play computer games","watch TV","listen to music"}),

    new Employee("004","Antony",30,new DateTime(2010,11,20),Sex.Male,Department.FD,320000, new string[] { "play chess","run"}),

    new Employee("005","Asa",28,new DateTime(2014,10,10),Sex.Female,Department.FD,120000,new string[] { "shopping"}),

    new Employee("006","Bernie",31,new DateTime(2008,4,5),Sex.Male,Department.PD,220000,new string[] { "play basketball"}),

    new Employee("007","Carl",26,new DateTime(2015,1,30),Sex.Male,Department.QC,100000,new string[] { "play chess","go fishing"}),

    new Employee("008","Duncan",30,new DateTime(2009,6,9),Sex.Male,Department.MD,250000,new string[] { "play computer games"}),

    new Employee("009","Aimee",24,new DateTime(2017,1,20),Sex.Female,Department.HR,80000,new string[] { "reading","run"}),

    new Employee("010","Cassie",31,new DateTime(2014,3,3),Sex.Female,Department.IT,350000,new string[] { "watch TV" })

};


1)筛选操作符(Where、OfType<TResult>)

Where:根据表达式函数过滤元素

 //查询年龄大于30岁,IT或HR部门所有员工的编号及姓名var filter = from r in employees                    where r.Age > 30 && (r.Department == Department.IT.ToString() || r.Department == Department.HR.ToString())            
         select r;    
        foreach (var item in filter){Console.WriteLine("EmployId: " +item.EmployeeId + " EmployeeName: " + item.EmployeeName);}      

OfType<TResult>:类型筛选

 //筛选出指定数组中所有int类型的元素object[] data = { "One", 2, 3, "Four", "Five", 6 };        var typeFilter = data.OfType<int>();        foreach (var item in typeFilter){Console.WriteLine(item);}       

2)投射操作符(Select、SelectMany)

Select:根据选择器函数选择的结果值投射到新的类型元素上

SelectMany:C#编译器把复合的from子句和LINQ查询转换为SelectMany扩展方法,用于迭代序列的序列。

        //查找个人爱好中有reading的员工的姓名var doubleFrom = from r in employees                         from h in r.Hobby                         where h == "reading"select r.EmployeeName;        foreach (var item in doubleFrom){Console.WriteLine(item);}       //--------------------------强势分隔符--------------------------------//使用SelectMany扩展方法返回个人爱好中有reading的员工的姓名var selectMany = employees.SelectMany(r => r.Hobby,(r, h) => new { Employee = r, Hobby = h }).Where(r => r.Hobby == "reading").Select(r => r.Employee.EmployeeName);        foreach (var item in selectMany){Console.WriteLine(item);}        //******************************Output*******************************//Jack//Aimee//*******************************************************************

3)排序操作符(OrderBy、ThenBy、OrderByDescending、ThenByDescending、Reverse)

OrderBy、OrderByDescending:升序排序、降序排序

ThenBy、ThenByDescending:如果第一次排序有元素相同,进行第二次排序(使用LINQ查询时只需把需要排序的关键字用逗号隔开)

  //按照年龄从大到小排序,如果年龄相同,则按照员工编号正向排序,输出员工的编号、姓名、年龄,var orderBy = from o in employees                      orderby o.Age descending, o.EmployeeId                      select o;        foreach (var item in orderBy){Console.WriteLine("EmployeeId: " + item.EmployeeId + " EmployeeName:" + item.EmployeeName + " Age:" + item.Age);}       //--------------------------强势分隔符--------------------------------//使用ThenBy扩展方法实现年龄相同,按员工编号正向排序var thenBy = employees.OrderByDescending(t => t.Age).ThenBy(t => t.EmployeeId).Select(t => "EmployeeId: " + t.EmployeeId + " EmployeeName:" + t.EmployeeName + " Age:" + t.Age);        foreach (var item in thenBy){Console.WriteLine(item);}       

Revise:使用扩展方法反转集合中的元素顺序

        //按照年龄从大到小排序后再反转元素的顺序var reverse = employees.OrderByDescending(r => r.Age).Reverse().Select(r => "EmployeeId: " + r.EmployeeId + " EmployeeName:" + r.EmployeeName + " Age:" + r.Age);foreach (var item in reverse){            Console.WriteLine(item);}       

4)连接操作符(Join、GroupJoin)

为了完成这部分的示例,我们需要准备新的实体类和列表


创建列表departmentInfo保存各部门的信息

        List<DepartmentInfo> deparmentInfo = new List<DepartmentInfo>(){            new DepartmentInfo("001","HR","Oliver"),            new DepartmentInfo("002","IT","Oscar"),            new DepartmentInfo("003","PD","ELLA"),            new DepartmentInfo("004","FD","Alice"),            new DepartmentInfo("005","QC","Kai")};

创建列表outstandingTeams保存2010年起获得杰出团队的部门

        List<OutstandingTeam> outstandingTeams = new List<OutstandingTeam>(){            new OutstandingTeam(2010,"IT"),            new OutstandingTeam(2011,"FD"),            new OutstandingTeam(2012,"HR"),            new OutstandingTeam(2013,"IT"),            new OutstandingTeam(2014,"QC"),            new OutstandingTeam(2015,"HR"),            new OutstandingTeam(2016,"HR"),            new OutstandingTeam(2017,"MD")};

Join:根据特定的条件合并两个数据源

        //查询员工的姓名,部门以及该部门的总监var join = from j in employees                   join d in deparmentInfoon j.Department equals d.DepartmentName                   select new{j.EmployeeName,j.Department,d.Director};        foreach (var item in join){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Department:" + item.Department + " Director:" + item.Director);}       

这时候我们会发现,输出的内容里面少了员工Duncan的信息,检查后发现,原来deparmentInfo没有添加MD部门的相关信息,此时希望查询所有员工,若匹配不到该部门信息,Director返回N/A。

        //查询员工的姓名,部门以及该部门的总监,若匹配不到该部门信息,Director返回N/Avar leftjoin = from j in employees                       join d in deparmentInfoon j.Department equals d.DepartmentName into jd            
                  from d in jd.DefaultIfEmpty()                       select new{j.EmployeeName,j.Department,Director = d == null ? "N/A" : d.Director};    
          foreach (var item in leftjoin){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Department:" + item.Department + " Director:" + item.Director);}      

GroupJoin:基于键相等对两个序列的元素进行关联并对结果进行分组。

        //查找每个部门获得杰出团队的年份var groupJoin = from d in deparmentInfo                        join o in outstandingTeams on d.DepartmentName equals o.Department into g                        select new{DepartmentName = d.DepartmentName,Years = g };   
        foreach (var item in groupJoin){Console.WriteLine("Department:" + item.DepartmentName);            if (item.Years.Count() == 0){Console.WriteLine("Never won the award");}            foreach (var champions in item.Years){Console.WriteLine(champions.Year);}}      

5)组合操作符(GroupBy、ToLookup)

GroupBy:根据关键字值对查询结果进行分组。

        //查询每个部门及人数var groupBy = from e in employees                      group e by e.Department into g                      select new{g.Key,Count = g.Count()};        foreach (var item in groupBy){Console.WriteLine("Department: " + item.Key + " Count: " + item.Count);}       

ToLookup:通过创建一对多的字典来组合元素

        //使用ToLookup实现爱好阅读的员工姓名var toLookup = (from e in employees                        from h in e.Hobby                        select new{Hobby = h,Name = e.EmployeeName}).ToLookup(he => he.Hobby, he => he.Name);      
         if (toLookup.Contains("reading")){          
        foreach (var item in toLookup["reading"]){Console.WriteLine(item);}}      

6)限定操作符(Any、All、Contains)

Any:是否包含满足条件的元素

 //是否有小于20岁的员工bool any = employees.Any(r => r.Age < 20);Console.WriteLine(any);       

ALL:是否所有元素都满足条件

 //是否所有员工都大于20岁bool all = employees.All(r => r.Age > 20);Console.WriteLine(all);       

Contains:检索某个元素是否在集合中

        //员工列表中是否包含davidEmployee david = new Employee("011", "David", 28, new DateTime(2017, 5, 21), Sex.Male, Department.IT, 100000, new string[] { "run" });employees.Add(david);        bool contains = employees.Contains(david);Console.WriteLine(contains);       

7)分区操作符(Take、Skip、TakeWhile、SkipWhile)

Take:从集合中提取指定数量的元素

Skip:跳过集合中指定数量的元素

        //忽略薪水最高的5位,查询剩余部分薪水最高的员工姓名及薪水var skip = (from e in employees                    orderby e.Salary descendingselect e).Skip(5).Take(1);        foreach (var item in skip){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);}        //******************************Output*******************************//EmployeeName: Mike Salary: 200000//*******************************************************************

TakeWhile:提取条件为真时的元素

        //取集合中满足条件salary大于1000000之前的所有员工的姓名和薪水var takeWhile = (from e in employees                         select e).TakeWhile(r => r.Salary > 100000);        foreach (var item in takeWhile){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);}       

SkipWhere:跳过集合中满足条件的元素,当条件不成立时返回剩余的所有元素

        //跳过集合中满足条件salary大于100000的元素,当条件不成立时返回剩余的所有元素var skipWhile = (from e in employees                         select e).SkipWhile(r => r.Salary > 100000);        foreach (var item in skipWhile){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);}       

8)Set操作符(Distinct、Union、Intersect、Except、Zip)

Distinct:从集合中删掉重复的元素

        //给所有员工的薪水排序,去掉重复的var distinct = (from e in employees                        orderby e.Salary select e.Salary).Distinct();        foreach (var item in distinct){Console.WriteLine(item);}       

Union、Intersect、Except:并集、交集、差集

首先,我们准备两个集合:员工姓名以A开头和员工姓名以E结尾

        var startWithA = (from e in employees                          where e.EmployeeName.StartsWith("A")                          select e).ToList();        var endWithE = (from e in employees                        where e.EmployeeName.ToUpper().EndsWith("E")                        select e).ToList();

以下分别取两个集合的并集、交集、差集:

        //查询两个集合的并集var union = startWithA.Union(endWithE);foreach (var item in union)        {            Console.WriteLine(item.EmployeeName);        }//--------------------------强势分隔符--------------------------------//查询两个集合的交集var intersect = startWithA.Intersect(endWithE);foreach (var item in intersect)        {            Console.WriteLine(item.EmployeeName);        }//查询两个集合的差集var except = startWithA.Except(endWithE);foreach (var item in except)        {            Console.WriteLine(item.EmployeeName);        }

Zip:把两个集合中对应的项目合并起来,在到大较小集合的末尾时停止

        //把两个集合中对应的项的姓名合并起来var zip = startWithA.Zip(endWithE, (first, second) => first.EmployeeName + "+" + second.EmployeeName);foreach (var item in zip){            Console.WriteLine(item);}       

9)元素操作符(First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Single、SingleOrDefault)

First:返回第一个满足条件的元素;若不存在,则引发异常。

FirstOrDefault:返回第一个满足条件的元素;若不存在,则返回默认值。

        //查询年龄大于30岁的第一位员工的姓名var first = (from e in employees                     orderby e.Age                
         select e).First(r => r.Age > 30);Console.WriteLine(first.EmployeeName);      

假设需查询年龄大于50岁的第一位员工的姓名,我们将上述代码中年龄修改为50

        var first = (from e in employees                     orderby e.Age                     select e).First(r => r.Age > 50);Console.WriteLine(first.EmployeeName);

执行后发现异常

此时使用FirstOrDefault操作符:

        //查询年龄大于50岁的第一位员工的姓名,若不存在,则返回N/Avar firstOrDefault = (from e in employees                              orderby e.Age                              select e).FirstOrDefault(r => r.Age > 50);Console.WriteLine(firstOrDefault == null ? "N/A" : firstOrDefault.EmployeeName);       

Last:返回最后一个满足条件的元素;若不存在,则引发异常。

LastOrDefault:返回最后一个满足条件的元素;若不存在,则返回默认值。

ElementAt:返回指定索引位置的元素;若不存在,则引发异常。

ElementAtOrDefault:返回指定索引位置的元素;若不存在,则返回默认值。

Single:只返回一个满足条件的元素;若不存在或多个元素都满足条件,则引发异常。

SingleOrDefault:只返回一个满足条件的元素;若不存在或多个元素都满足条件,则返回默认值。

10)聚合操作符(Count、Sum、Min、Max、Average、Aggregate)

Count:返回集合中的项数

        //查找有一个以上爱好的员工的姓名、爱好的数量及部门var count = from e in employees                    let numberHobby = e.Hobby.Count()                    where numberHobby > 1select new{e.EmployeeName,numberHobby,e.Department};        foreach (var item in count){Console.WriteLine("EmployeeName: " + item.EmployeeName + " NumberHobby: " + item.numberHobby + " Department: " + item.Department);}       

Sum:计算所有值的总和

Min、Max、Average:最小值、最大值、平均值

        //计算所有员工薪水的总和var sum = (from e in employees                   select e.Salary).Sum/*Min、Max、Average*/();Console.WriteLine(sum.ToString("N0"));       

Aggregate:对序列进行累加

        //初始值为50000000,依次累加所有员工的薪水var aggregate = (from e in employees                         select e.Salary).Aggregate(5000000, (x, y) => x + y, r => r * 2);Console.WriteLine(aggregate.ToString("N0"));     

说明:Aggregate扩展方法的第一个参数为初始值。第二个参数是一个表达式,用来对每个元素进行计算(第一个参数是累加变量,第二个参数是当前值)。第三个参数是一个表达式,用来对最终结果进行计算。

11)转换操作符(ToArray、AsEnumerable、ToList、ToDictionary、Cast<TResult>)

使用转换操作符会立即执行查询,将查询结果放在数组、列表、字典中。

        //将年龄大于30岁的元素放入list中再循环输出。List<Employee> employeeList = (from e in employees                                       where e.Age > 30select e).ToList();        foreach (var item in employeeList){Console.WriteLine("EmployeeName: " + item.EmployeeName + " Age:" + item.Age);}       

12)生成操作符(Empty、Range、Repeat)

生成操作符不是扩展方法,而是返回序列的静态方法。在LINQ to Objects中,这些方法可用于Enumerable类。

Empty:生成空集合

        //生成一个int类型的空序列var empty = Enumerable.Empty<int>();          Console.WriteLine(empty.Count());       

Range:生成一系列数字的集合

        //生成一个从1开始,10个元素的序列var range = Enumerable.Range(1, 10);        foreach (var item in range){Console.WriteLine(item);}       

Repeat:返回始终重复一个值的集合

        //生成一个10个元素,每个元素都是5的序列var repeat = Enumerable.Repeat(5, 10);foreach (var item in repeat)        {            Console.WriteLine(item);        }

本篇就此结束,主要介绍了LINQ的体系结构、基本语法以及LINQ to Obejcts中标准查询操作符的使用方法。

示例代码下载:https://github.com/Answer-Geng/LINQ

原文地址:http://www.cnblogs.com/Answer-Geng/p/6881953.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单点登录终极方案之 CAS 应用及原理

转载自 单点登录终极方案之 CAS 应用及原理 Cookie的单点登录的实现方式很简单&#xff0c;但是也问题颇多。例如&#xff1a;用户名密码不停传送&#xff0c;增加了被盗号的可能。另外&#xff0c;不能跨域&#xff01; 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录…

微软亚太区资料科学总监:R 语言是 VS 生态第一顺位

微软亚太区资料科学总监Graham Williams 微软在2015年并购R语言工具商Revolution Analytics之后&#xff0c;随即在2016年&#xff0c;也开始在自家主力开发工具Visual Studio上&#xff0c;支持R语言。微软将如何定位R语言在微软开发工具链的位置&#xff1f;微软亚太区资料科…

java中如何数组是如何赋值的?

由于数组是引用类型&#xff0c;故无法与变量赋值的方式一样&#xff0c;int a 10;int b a; 那么数组是如何赋值的呢&#xff1f; 是这样赋值的&#xff1a; public static void arrayFuZhi(){//八斤的身高和体重int [] ba {170,80};//九斤的身高和体重与八斤的一样int [] …

从LINQ开始之LINQ to Objects(下)

前言 上一篇《从LINQ开始之LINQ to Objects&#xff08;上&#xff09;》主要介绍了LINQ的体系结构、基本语法以及LINQ to Objects中标准查询操作符的使用方法。 本篇则主要讨论LINQ to Objects中的扩展方法以及延迟加载等方面的内容。 扩展方法 1.扩展方法简介 扩展方法能够向…

Localdatetime

根据指定日期/时间创建对象 LocalDate localDate LocalDate.of(2018, 1, 13); LocalTime localTime LocalTime.of(9, 43, 20); LocalDateTime localDateTime LocalDateTime.of(2018, 1, 13, 9, 43, 20); System.out.println(localDate); System.out.println(localTime); Sy…

基于OAuth2的认证(译)

OAuth 2.0 规范定义了一个授权&#xff08;delegation&#xff09;协议&#xff0c;对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用程序中&#xff0c;包括提供用户认证的机制。这导致许多的开发者和API提供者得出一个OAuth本身是一个认证…

Redis非阻塞I/O多路复用机制

小曲在S城开了一家快递店&#xff0c;负责同城快送服务。小曲因为资金限制&#xff0c;雇佣了一批快递员&#xff0c;然后小曲发现资金不够了&#xff0c;只够买一辆车送快递。 经营方式一 客户每送来一份快递&#xff0c;小曲就让一个快递员盯着&#xff0c;然后快递员开车去…

React前端格式化时间

import moment from "moment";const dateFormat YYYY-MM-DD HH:mm:ss;<DatePicker label"时间" name"insertTime" showTime onChange{onChange} onOk{onOk}defaultValue{moment(location?.defaultValues?.record?.insertTime, dateFormat…

[认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)

1 什么是OIDC&#xff1f; 看一下官方的介绍&#xff08;http://openid.net/connect/&#xff09;&#xff1a; OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the a…

EasyExcel中输出为时间格式

前端传值 后端Excel配置为String类型 配置为其他类型显示格式转化异常

Identity Service - 解析微软微服务架构eShopOnContainers(二)

接上一篇&#xff0c;众所周知一个网站的用户登录是非常重要&#xff0c;一站式的登录&#xff08;SSO&#xff09;也成了大家讨论的热点。微软在这个Demo中&#xff0c;把登录单独拉了出来&#xff0c;形成了一个Service&#xff0c;用户的注册、登录、找回密码等都在其中进行…

TCP/IP协议——ARP详解

转载自 TCP/IP协议——ARP详解 本文主要讲述了ARP的作用、ARP分组格式、ARP高速缓存、免费ARP和代理ARP。 1.学习ARP前要了解的内容 建立TCP连接与ARP的关系 应用接受用户提交的数据&#xff0c;触发TCP建立连接&#xff0c;TCP的第一个SYN报文通过connect函数到达IP层&a…

RPC远程过程调用之 RMI实现

1&#xff09;RMI&#xff08;remote method invocation&#xff09;是java原生支持的远程调用&#xff0c;RMI采用JRMP&#xff08;java RemoteMessageing Protocol&#xff09;作为通信协议。可以认为是纯java版本的分布式远程调用解决方法。 2&#xff09;RMI的核心概念 3&…

[翻译]编写高性能 .NET 代码 第一章:性能测试与工具 -- 选择什么来衡量

选择什么来衡量 在搜集数据测试数据前&#xff0c;你需要知道你要以怎样的指标来衡量测试结果。这听起来很容易&#xff0c;但实际上比你想象中的要难许多。如果你想降低内存使用量&#xff0c;你会选择什么方式呢&#xff1f; 私有工作集&#xff08;Private working set&am…

RPC远程过程调用之Hessian 基于HTTP

Hessian使用C/S方式&#xff0c;基于HTTP协议传输&#xff0c;使用Hessian二进制序列化。 添加依赖&#xff1a; <dependency><groupId>com.caucho</groupId><artifactId>hessian</artifactId><version>4.0.7</version> </depen…

EF框架中,在实体中手动更新字段,数据库数据未同步到程序中应该怎么解决呢?

在一些技术不是很强的选手手中&#xff0c;设计数据库时&#xff0c;难免会未考虑到某些字段&#xff0c;只能到后期实现功能时&#xff0c;才能觉察出来数据库中或是少写字段&#xff0c;或是多加了无用的字段&#xff0c;故我们还不得不去数据库中做些手脚。 本文列举的是在…

[.NET跨平台]Jexus独立版本的便利与过程中的一些坑

本文环境与前言 之前写过一篇相关的文章:在.NET Core之前,实现.Net跨平台之MonoCentOSJexus初体验 当时的部署还是比较繁琐的,而且需要联网下载各种东西..有兴趣的可以看看,但是..已经过时了.. 虽然已经出了.NET Core2.0 但是目前是预览版本,而且部署来说 相对比较麻烦. 今…

《四世同堂》金句摘抄(二)

System.out.println("今天读的是什么书呢&#xff1f;"); String bname "《四世同堂》"; System.out.println("今天读的书是&#xff1a;"bname);Console.WriteLine("今天读的是什么书呢&#xff1f;"); String bname "《四世同…

码农不重视文档:开源项目深受其苦

GitHub 刚刚发布了《2017 开源调查》报告&#xff0c;这家知名编程社交网站走访了 github.com 社区内 3800 多个项目和超过 5500 名成员&#xff0c;并且与 500 名在 GitHub 项目生态系统之外的编程者们进行了交谈。本次调查涉及多方面&#xff0c;比如人们在为开源项目做开发、…