广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >c# Linq查询详解
  • 448
分享到

c# Linq查询详解

2024-04-02 19:04:59 448人浏览 薄情痞子
摘要

目录基本查询 延迟查询属性 类型筛选 复合from子句 多级排序 分组 联合查询-join 合并-zip() 分区(分页) 并行linq 取消长时间运行的并行linq查询 C#提供的

C#提供的ling查询极大的遍历了集合的查询过程,且使用简单方便,非常的有用。

下面将分别用简单的例子说明:ling基本查询、延迟查询属性、类型筛选、复合from字句、多级排序、分组查询、联合查询、合并、分页、聚合操作符、并行linq、取消长时间运行的并行ling查询。

Lambda表达式简介:



              delegate int del(int i);  
              static void Main(string[] args)
              { 
                   del myDelegate = x => x * x;  
                   int j = myDelegate(5); //最后j = 25  
               }

基本查询

语句:


 var query = from r in listStudents where r.score < 60 orderby r.score descending select r;
 //var q2 = listStudents.Where(r => r.score < 60).OrderByDescending(r => r.score).Select(r => r) ;//或使用Lambda表达式

例子:


/// <summary>
        /// 学生结构体
        /// </summary>
        struct Student
        {
            /// <summary>
            /// 姓名
            /// </summary>
            public string name;
            /// <summary>
            /// 年龄
            /// </summary>
            public int age;
            /// <summary>
            /// 班号
            /// </summary>
            public int grade;
            /// <summary>
            /// 分数
            /// </summary>
            public float score;
        }
/// <summary>
        /// linq
        /// 基本查询
        /// </summary>
        static void Linq1()
        {
            #region 构造查询数据
            List<Student> listStudents = new List<Student>();
            Random pRandom = new Random();
            for (int i = 1; i < 50; i++)
            {
                float sc = pRandom.Next(0, 100);
                int age = pRandom.Next(8, 13);
                int gde = pRandom.Next(1, 6);

                string name = "";
                switch (pRandom.Next(0, 6))
                {
                    case 1: name = "周xxx"; break;
                    case 2: name = "李xxx"; break;
                    case 3: name = "孙xxx"; break;
                    case 4: name = "钱xxx"; break;
                    default: name = "赵xxx"; break;
                }

                Student psdt = new Student();
                psdt.name = name;
                psdt.age = age;
                psdt.grade = gde;
                psdt.score = sc;
                listStudents.Add(psdt);
            }
            #endregion
            //从50个学生中选择出不及格的人员名单并按分数降序排列
            var query = from r in listStudents where r.score < 60 orderby r.score descending select r;
            //var q2 = listStudents.Where(r => r.score < 60).OrderByDescending(r => r.score).Select(r => r) ;//或使用Lambda表达式
            //orderby升序即从小到大,orderby r.score descending降序即从大到小

            Console.WriteLine("不及格的人员名单:");
            foreach (Student st in query)
            {
                Console.WriteLine("***************");
                Console.WriteLine("姓名:"+st.name);
                Console.WriteLine("班级:"+st.grade);
                Console.WriteLine("年龄:"+st.age);
                Console.WriteLine("分数:"+st.score);
            }
            Console.ReadKey();
        }

延迟查询属性

linq查询为延迟查询,只需构造一次查询语句,可以多次使用。

例子:


/// <summary>
        /// Linq
        /// 延迟查询
        /// linq查询为延迟查询,只需构造一次查询语句,可以多次使用
        /// </summary>
        static void Linq2()
        {
            #region 构造查询数据
            List<string> lists = new List<string> { "Jack","Pet","Hant","Li","Kkk"};
            
            #endregion
            var query = from r in lists where r.StartsWith("J") select r;
            Console.WriteLine("第一次查询结果:");
            foreach (string st in query)
            {
                Console.WriteLine( st);
            }

            Console.WriteLine("第二次查询结果:");
            lists.Add("Jone");
            lists.Add("Jimi");
            lists.Add("Johu");
            foreach (string st in query)
            {
                Console.WriteLine(st);
            }

            Console.ReadKey();
            
        }

类型筛选

利用OfType方法可以把特定类型数据筛选出来。

例子


/// <summary>
        /// Linq类型筛选-ofType
        /// </summary>
        static void Linq3()
        {
            object[] pList = new object[] { 1,"one",2,"two",3,"three"};
            var query = pList.OfType<string>();
            foreach (var st in query)
            {
                Console.WriteLine(st);
            }
            Console.ReadKey();
            
        }

复合from子句

语句:


 var query = from s in listStudents 
                        from n in s.name 
                        where n == '赵' orderby s.score descending 
                        select s.grade + "班-" + s.name + ",分数" + +s.score;
            

例子:


/// <summary>
        /// linq复合from字句
        /// </summary>
        static void Linq4()
        {
            #region 构造查询数据
            List<Student> listStudents = new List<Student>();
            Random pRandom = new Random();
            for (int i = 1; i < 50; i++)
            {
                float sc = pRandom.Next(0, 100);
                int age = pRandom.Next(8, 13);
                int gde = pRandom.Next(1, 6);

                string name = "";
                switch (pRandom.Next(0, 6))
                {
                    case 1: name = "周xxx"; break;
                    case 2: name = "李xxx"; break;
                    case 3: name = "孙xxx"; break;
                    case 4: name = "钱xxx"; break;
                    default: name = "赵xxx"; break;
                }

                Student psdt = new Student();
                psdt.name = name;
                psdt.age = age;
                psdt.grade = gde;
                psdt.score = sc;
                listStudents.Add(psdt);
            }
            #endregion
            var query = from s in listStudents 
                        from n in s.name 
                        where n == '赵' orderby s.score descending 
                        select s.grade + "班-" + s.name + ",分数" + +s.score;
            
            foreach (var t in query)
            {
                Console.WriteLine(t);
            }
            Console.ReadKey();
        }

多级排序

语句:


 //参数越靠前,优先级越高
            //先按score排序,当分数相同时再按grade排序...依次类推
            var query = from s in listStudents orderby s.score, s.grade, s.age, s.name select s;

例子:


/// <summary>
        /// 多级排序
        /// </summary>
        static void Linq5()
        {
            #region 构造查询数据
            List<Student> listStudents = new List<Student>();
            Random pRandom = new Random();
            for (int i = 1; i < 50; i++)
            {
                float sc = pRandom.Next(0, 100);
                int age = pRandom.Next(8, 13);
                int gde = pRandom.Next(1, 6);

                string name = "";
                switch (pRandom.Next(0, 6))
                {
                    case 1: name = "周xxx"; break;
                    case 2: name = "李xxx"; break;
                    case 3: name = "孙xxx"; break;
                    case 4: name = "钱xxx"; break;
                    default: name = "赵xxx"; break;
                }

                Student psdt = new Student();
                psdt.name = name;
                psdt.age = age;
                psdt.grade = gde;
                psdt.score = sc;
                listStudents.Add(psdt);
            }
            #endregion
            //参数越靠前,优先级越高
            //先按score排序,当分数相同时再按grade排序...依次类推
            var query = from s in listStudents orderby s.score, s.grade, s.age, s.name select s;
            foreach (Student st in query)
            {
                Console.WriteLine("***************");
                Console.WriteLine("姓名:" + st.name);
                Console.WriteLine("班级:" + st.grade);
                Console.WriteLine("年龄:" + st.age);
                Console.WriteLine("分数:" + st.score);
            }
            Console.ReadKey();
        }

分组

语句:


//按国家分组,并选出大于2的组,形成新的集合
            var query = from r in listChampion
                        group r by r.country into g
                        orderby g.Count() descending, g.Key
                        where g.Count() >= 2
                        select
                            new { country = g.Key, count = g.Count() };

例子:


/// <summary>
        /// 分组
        /// </summary>
        static void Linq6()
        {
            List<Champions> listChampion = new List<Champions>();
            listChampion.Add(new Champions() { name = "张**", country = "中国" });
            listChampion.Add(new Champions() { name = "赵**", country = "中国" });
            listChampion.Add(new Champions() { name = "李**", country = "中国" });
             listChampion.Add(new Champions() { name = "李**", country = "中国" });
            listChampion.Add(new Champions() { name = "Peter", country = "美国" });
            listChampion.Add(new Champions() { name = "Hune", country = "美国" });
              listChampion.Add(new Champions() { name = "Hune", country = "美国" });
            listChampion.Add(new Champions() { name = "Jack", country = "俄罗斯" });
              listChampion.Add(new Champions() { name = "Jack", country = "俄罗斯" });
            listChampion.Add(new Champions() { name = "Jimi", country = "英国" });
            //按国家分组,并选出大于2的组,形成新的集合
            var query = from r in listChampion
                        group r by r.country into g
                        orderby g.Count() descending, g.Key
                        where g.Count() >= 2
                        select
                            new { country = g.Key, count = g.Count() };
            foreach (var o in query)
            {
                Console.WriteLine("国家:{0},冠军数:{1}个", o.country, o.count);
            }
            Console.ReadKey();
        }

联合查询-join

语句:


//查询出集合qSt中year等于集合qSc中year的元素并形成新的集合
            var qjoin = from r in qSt 
                        join c in qSc 
                        on r.year equals c.year 
                        select new 
                        {
                            Year = r.year, 
                            stName = r.name,
                            scName = c.name 
                        };

例子:


/// <summary>
        /// 联合查询-join
        /// </summary>
        static void Linq7()
        {
            List<s> pSt = new List<s>();
            pSt.Add(new s() {year=1999,name="xxx" });
            pSt.Add(new s() { year = 2000, name = "xxx" });
            pSt.Add(new s() { year = 2001, name = "xxx" });
            pSt.Add(new s() { year = 2010, name = "xxx" });
            List<school> pSc = new List<school>();
            pSc.Add(new school() { year = 1999, name = "***" });
             pSc.Add(new school() { year = 2001, name = "***" });
            pSc.Add(new school() { year = 2002, name = "***" });
            pSc.Add(new school() { year = 2010, name = "***" });
            pSc.Add(new school() { year = 2012, name = "***" });

            var qSt = from r in pSt where r.year >= 2000 select r;
            var qSc = from r in pSc where r.year >= 2000 select r;

            //查询出集合qSt中year等于集合qSc中year的元素并形成新的集合
            var qjoin = from r in qSt 
                        join c in qSc 
                        on r.year equals c.year 
                        select new 
                        {
                            Year = r.year, 
                            stName = r.name,
                            scName = c.name 
                        };

            foreach (var ite in qjoin)
            {
                Console.WriteLine(ite.Year + " " + ite.scName + " " + ite.stName);
                Console.WriteLine("");
            }
            Console.ReadKey();
        }

合并-zip()

.net4.0新增,可对两个相关的序列进行合并。

语句:


  
            var qZip = qSc.Zip(qSt, (first, second) =>string.FORMat("Year:{0},Name:{1}.", first.Year,second.Name));//返回值qZip为字符串集合

例子:


/// <summary>
        /// 合并-zip()-.Net4.0新增,可对两个相关的序列进行合并
        /// </summary>
        static void Linq8()
        {
            List<s> pSt = new List<s>();
            pSt.Add(new s() { year = 1999, name = "一xxx" });
            pSt.Add(new s() { year = 2000, name = "二xxx" });
            pSt.Add(new s() { year = 2001, name = "三xxx" });
            pSt.Add(new s() { year = 2010, name = "四xxx" });
            pSt.Add(new s() { year = 2010, name = "五xxx" });
            List<school> pSc = new List<school>();
            pSc.Add(new school() { year = 1999, name = "1***" });
            pSc.Add(new school() { year = 2012, name = "2***" });
            pSc.Add(new school() { year = 2012, name = "3***" });
            pSc.Add(new school() { year = 2012, name = "4***" });
            pSc.Add(new school() { year = 2012, name = "5***" });

            var qSt = from r in pSt where r.year >= 2000 orderby r.year select new { Year = r.year, Name = r.name };
            var qSc = from r in pSc where r.year >= 2000 orderby r.year select new { Year = r.year, Name = r.name };
            
            var qZip = qSc.Zip(qSt, (first, second) =>string.Format("Year:{0},Name:{1}.", first.Year,second.Name));//返回值qZip为字符串集合
           
            foreach (var ite in qZip)
            {
                Console.WriteLine(ite);
            }
            Console.ReadKey();

        }

分区(分页)

通过Take()和Skip()实现只显示部分查询结果。

语句:


 //通过skip跳过指定数量的元素,再通过take提取固定长度元素,可实现分页
                var qr = (from r in listStudents orderby r.score descending select r).Skip(i * pageSize).Take(5);
                //var qr2 = listStudents.OrderByDescending(r => r.score).Select(r => r).Skip(i * pageSize).Take(5);//或

例子


/// <summary>
        /// 分区(分页)-通过Take()和Skip()实现只显示部分查询结果
        /// </summary>
        static void Linq9()
        {
            #region 构造查询数据
            List<Student> listStudents = new List<Student>();
            Random pRandom = new Random();
            for (int i = 1; i < 50; i++)
            {
                float sc = pRandom.Next(0, 100);
                int age = pRandom.Next(8, 13);
                int gde = pRandom.Next(1, 6);

                string name = "";
                switch (pRandom.Next(0, 6))
                {
                    case 1: name = "周xxx"; break;
                    case 2: name = "李xxx"; break;
                    case 3: name = "孙xxx"; break;
                    case 4: name = "钱xxx"; break;
                    default: name = "赵xxx"; break;
                }

                Student psdt = new Student();
                psdt.name = name;
                psdt.age = age;
                psdt.grade = gde;
                psdt.score = sc;
                listStudents.Add(psdt);
            }
            #endregion

            int pageSize = 5;
            int numofPage = (int)Math.Ceiling(listStudents.Count /(double)pageSize);

            for (int i = 0; i < numofPage; i++)
            {
                Console.WriteLine("第{0}页", i);

                //通过skip跳过指定数量的元素,再通过take提取固定长度元素,可实现分页
                var qr = (from r in listStudents orderby r.score descending select r).Skip(i * pageSize).Take(5);
                //var qr2 = listStudents.OrderByDescending(r => r.score).Select(r => r).Skip(i * pageSize).Take(5);//或
                foreach (var ite in qr)
                {
                    Console.WriteLine(ite.name);
                    Console.WriteLine(ite.score);
                }
                Console.WriteLine("");
            }
            Console.ReadKey();
        }

并行linq

并行查询可以分解查询的工作,使其分布在多个线程上。当pc拥有多个cpu时,可以看到并行查询带来的改进效果。并行LINQ适用于大型的集合查询,并拥有一定的优势。使用

System.Collections.Concurrent.Partitioner.Create
可以手动创建分区器。
语法:


var sum2 = (from x2 in data.AsParallel() where x2 > 20 select x2).Sum();//并行查询

//var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或并行查询(Lambda表达式)

例子:


/// <summary>
        /// 并行linq
        /// </summary>
        static void Linq11()
        {
            Console.WriteLine("开始构造大数组...");
            //构造大数组
            const int count = 100000000;
            var data = new int[count];
            var r = new Random();
            for (int i = 0; i < count; i++)
            {
                data[i] = r.Next(40);
            }
            Console.WriteLine("开始计算...");
            var st = System.DateTime.Now;
            var sum = (from x in data where x > 20 select x).Sum();//常规linq-耗时1.8641s
            var st2 = System.DateTime.Now;
            var sum2 = (from x2 in data.AsParallel() where x2 > 20 select x2).Sum();//并行查询-耗时0.6620s

            //var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或并行查询----x3 => x3 > 20(Lambda表达式)
            var st3 = System.DateTime.Now;

            
            var sum4 = (from c in System.Collections.Concurrent.Partitioner.Create(data, true).AsParallel() where c > 20 select c).Sum();

            var dt1 = st2 - st;
            var dt2 = st3 - st2;
            Console.WriteLine("常规linq耗时:{0}s",dt1.TotalSeconds.ToString());
            Console.WriteLine("并行linq耗时:{0}s", dt2.TotalSeconds.ToString());
            Console.ReadKey();
        }

输出结果:

可以粗鲁的认为并行linq对于大集合的查询是优势比较明显的。

取消长时间运行的并行linq查询

对于并行ling而言,可以设置可以利用System.Threading.CancellationTokenSource设置取消操作。

语法:


 //通过.WithCancellation(cts.Token)设置
                    var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < 20 select x).Average();

例子:


/// <summary>
        /// 取消长时间运行的并行linq查询
        /// </summary>
        static void Linq12()
        {
            //构造大数组
            const int count = 100000000;
            var data = new int[count];
            var r = new Random();
            for (int i = 0; i < count; i++)
            {
                data[i] = r.Next(40);
            }

            var cts = new System.Threading.CancellationTokenSource();

            new System.Threading.Thread(() =>
            {
                try
                {
                    //通过.WithCancellation(cts.Token)设置
                    var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < 20 select x).Average();
                    Console.WriteLine("sum:{0}", sum);
                }
                catch(OperationCanceledException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }).Start();

            Console.WriteLine("计算开始...");
            Console.WriteLine("取消请按n!");
            var rk = Console.Read();
            if(rk=='n'||rk=='N')
            {
                cts.Cancel();
            }

        }

至此,对于LINQ已经有了一个基本的了解。

以上就是c# Linq查询详解的详细内容,更多关于c# Linq查询的资料请关注编程网其它相关文章!

--结束END--

本文标题: c# Linq查询详解

本文链接: https://www.lsjlt.com/news/123427.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c# Linq查询详解
    目录基本查询 延迟查询属性 类型筛选 复合from子句 多级排序 分组 联合查询-join 合并-zip() 分区(分页) 并行linq 取消长时间运行的并行linq查询 c#提供的...
    99+
    2022-11-12
  • C#集合查询Linq在项目中使用详解
    目录Linq LambdaLinq项目中的一次使用经历Linq to js [在前端的应用]要说哪门后端语言的语法优雅,那就不得不提C#,而在我看来,LINQ语法可以说是其优雅的重要...
    99+
    2022-11-13
  • C#中如何使用LINQ查询数据
    C#中如何使用LINQ查询数据,需要具体代码示例LINQ(Language Integrated Query)是C#中的一种强大的查询语言,它可以帮助开发者简化对数据的查询和操作。本文将介绍如何在C#中使用LINQ查询数据,并提供具体的代码...
    99+
    2023-10-22
    C# 查询数据 C#中的关键词: LINQ
  • C#如何使用LINQ查询操作符
    这篇文章主要讲解了“C#如何使用LINQ查询操作符”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#如何使用LINQ查询操作符”吧!连表操作符1、内连接使用 join 子句 根据特定的条件合...
    99+
    2023-07-02
  • LINQ查询架构怎么理解
    本篇内容主要讲解“LINQ查询架构怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINQ查询架构怎么理解”吧!LINQ(发音:Link)是Language Integrated Quer...
    99+
    2023-06-17
  • LINQ模糊查询怎么理解
    本篇内容主要讲解“LINQ模糊查询怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINQ模糊查询怎么理解”吧!LINQ模糊查询实现的意义:为了避免即使实现,效率也不是很高,LINQ提供了...
    99+
    2023-06-17
  • LINQ动态查询怎么理解
    本篇内容主要讲解“LINQ动态查询怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINQ动态查询怎么理解”吧!LINQ动态查询有这样一个场景:应用程序可能会提供一个用户界面,用户可以使用...
    99+
    2023-06-17
  • 怎么在c#中使用Linq查询语句
    怎么在c#中使用Linq查询语句?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Lambda表达式简介:      &...
    99+
    2023-06-14
  • C# Linq延迟查询的执行实例代码
    C# Linq延迟查询 在定义linq查询表达式时,查询是不会执行,查询会在迭代数据项时运行。它使用yield return 语句返回谓词为true的元素。 var names ...
    99+
    2022-11-12
  • 如何使用LINQ查询
    这篇文章主要介绍了如何使用LINQ查询,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。.NET Language Integrated Query (LINQ):采用通用方案来...
    99+
    2023-06-17
  • LINQ查询操作分析
    这篇文章主要介绍“LINQ查询操作分析”,在日常操作中,相信很多人在LINQ查询操作分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”LINQ查询操作分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!LI...
    99+
    2023-06-17
  • LINQ查询如何使用
    这篇文章主要讲解了“LINQ查询如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“LINQ查询如何使用”吧!LINQ查询成为了.NET中头等的编程概念,被查询的数据可以是XML(LINQ...
    99+
    2023-06-17
  • LINQ查询怎么使用
    本篇内容主要讲解“LINQ查询怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“LINQ查询怎么使用”吧!LINQ是Visual Studio 2008及其以后版本中提供的功能,将强大的查询...
    99+
    2023-06-17
  • SQL基础查询和LINQ集成化查询
    SELECT SELECT 语句用于从表中选取数据,是 SQL 最基本的操作之一。 通过 SELECT 查询的结果被存储在一个结果表中(称为结果集)。 SQL SELECT ...
    99+
    2022-11-12
  • C#中的LINQ to Objects详解(1)
    目录一、概述二、 Linq to Objects中的延迟计算1. Linq延迟计算的注意点2. 整理Linq to Objects中运算符延迟计算特性1、具有延迟计算的运算符2、立即...
    99+
    2022-11-13
  • C#中的LINQ to Objects详解(2)
    目录四、Linq和反射五、LINQ 和字符串1、LINQ 和文件目录实例1、如何查询具有指定属性或名称的文件实例2、如何按照扩展名对文件进行分组实例3、如何查询一组文件夹中的总字节数...
    99+
    2022-11-13
  • C#使用LINQ查询操作符实例代码(一)
    目录相关阅读示例业务背景介绍一、筛选操作符结果:1、索引器筛选2、类型筛选OfType二、投影操作符1、Select 子句结果:相应的lambda表达式:2、复合的From...
    99+
    2022-11-13
  • C#使用LINQ查询操作符实例代码(二)
    目录相关阅读六、连表操作符1、内连接2、左外连接(DefaultIfEmpty)3、组连接七、集合操作八、分区操作符1、Take():2、TakeWhile():3、Skip():4...
    99+
    2022-11-13
  • C#集合查询Linq在项目中如何使用
    这篇文章主要介绍“C#集合查询Linq在项目中如何使用”,在日常操作中,相信很多人在C#集合查询Linq在项目中如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#集合查询Linq在项目中如何使用”的疑...
    99+
    2023-06-30
  • LINQ查询操作的问题怎么解决
    这篇文章主要介绍“LINQ查询操作的问题怎么解决”,在日常操作中,相信很多人在LINQ查询操作的问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”LINQ查询操作的问题怎么解决”的疑惑有所帮助!接下来...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作