2013-01-30 11:12 12154人阅读 评论(0) 收藏 举报
 分类:
C#(14) 

文章转自:http://www.cnblogs.com/c-jquery-linq-sql-net-problem/archive/2011/01/17/LINQ_Inner_Join_Group_Join_Left_Join.html

我们在做SQL查询的时候经常会用到Inner Join,Left Join,笛卡尔积等等,连接方式的概念方面我想也不用给予太多解释,

我们今天的重点是让大家熟悉LINQ是如何使用Join来实现常用的表连接的。

创建测试用类:

  1. class Customer
  2. {
  3. public int CustomerId { get; set; }
  4. public string Name { get; set; }
  5. public int Age { get; set; }
  6. }
  7. class Product
  8. {
  9. public int ProductId { get; set; }
  10. public string Name { get; set; }
  11. public string Origin { get; set; }
  12. }
  13. class Order
  14. {
  15. public int OrderId { get; set; }
  16. public int CustomerId { get; set; }
  17. public List<Product> Products { get; set; }
  18. }

我们用以下例子来熟悉 Join 关键字的用法。

1.Inner Join:

  1. CreateEntities();
  2. var query = from c in customers
  3. join o in orders on c.CustomerId equals o.CustomerId
  4. where o.OrderId == 2
  5. select c;
  6. foreach (var customer in query)
  7. {
  8. Console.WriteLine("Id:{0}, Name:{1}", customer.CustomerId, customer.Name);
  9. }

 

运行结果:

  Id:1, Name:CA   

 上面这个是常见的内连接的例子,和SQL语法也很相似,但有以下几点要注意:

(1).连接条件: c.CustomerId equals o.CustomerId 只能使用 equals 不能用 =,==,等于 等表示。
以为LINQ的设计者认为 几乎所有的连接条件都是 = 条件不会出现 >,<,!= 等情况因此使用了个关键字来描述表连接条件。

(2).条件顺序:c.CustomerId equals o.CustomerId ,range variable: c 和b之前的顺序不能颠倒。

2.Group Join:

也许大家对Group Join的概念不太了解,没关系让我们通过例子来认识它:

  1. CreateEntities();
  2. var query = from c in customers
  3. join o in orders on c.CustomerId equals o.CustomerId into os
  4. select new { c, os };
  5. foreach (var item in query)
  6. {
  7. Console.WriteLine("Customer Id:{0}, Name:{1}", item.c.CustomerId, item.c.Name);
  8. foreach (var o in item.os)
  9. {
  10. Console.WriteLine("--Order Id:{0}", o.OrderId);
  11. }
  12. }

结果:

Customer Id:1, Name:CA
--Order Id:1
--Order Id:2
Customer Id:2, Name:CB
--Order Id:4
Customer Id:3, Name:CC
--Order Id:3
Customer Id:4, Name:CD
Press any key to continue . . .

以上查询返回的结果:和Group By 返回的结果非常的相似:一个KEY对象对应一个集合。

要实现Group Join我们要引入一个关键字:into

但使用时要注意一下几点:

(1).使用into 关键字后 join 后面的 range variable:o 在后面的表达式块中就失去了作用域。

(2).range variable:os 通常情况下都是IEnumerable<T>类型的。

3.Left Join:

 Left Join 我们在SQL里经常用到,让我们来看看LINQ里怎么实现它:

  1. CreateEntities();
  2. var query = from c in customers
  3. join o in orders on c.CustomerId equals o.CustomerId into os
  4. from o2 in os.DefaultIfEmpty(
  5. new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })
  6. select new { c, o2 };
  7. foreach (var item in query)
  8. {
  9. Console.WriteLine("Customer Id:{0}, Name:{1}--Order Id:{0}",
  10. item.c.CustomerId, item.o2.OrderId);
  11. }

结果:

Customer Id:1, Name:1--Order Id:1
Customer Id:1, Name:2--Order Id:1
Customer Id:2, Name:4--Order Id:2
Customer Id:3, Name:3--Order Id:3
Customer Id:4, Name:0--Order Id:4
Press any key to continue . . .

我们可以看到Left Outer Join 的语法进一步的复杂化了,结果也有细微的不同。

(1).从语法上:

from o2 in os.DefaultIfEmpty(
                new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })

主要区别在于以上者1句语句。查询方法DefaultIfEmpty 用于定义当查询记录为空时,预定义默认值。再从其集合中取出子元素。

(2).从结果上: 我们在遍历查询结果时可以发现Left Join相似于Inner Join结果都是“平面”的,然而Group Join返回的结果具有层次性。

题外:

由于C#是面向对象的,往往会通过对象与对象间的外系来实现数据间关系。有时表达2个之间的关系也可以不使用Join关键字,

因此Join关键字其实在实际LINQ查询表达式中用的不是很多。

# Linq获取两个List或数组的差集交集

 

List<int> list1 = new List<int>();
list1.Add(1);
list1.Add(2);
list1.Add(3);
List<int> list2 = new List<int>();
list2.Add(3);
list2.Add(4);
list2.Add(5);
//得到的结果是4,5 即减去了相同的元素。
List<int> list3 = list2.Except(list1).ToList();
foreach (int i in list3)
{
    MessageBox.Show(i.ToString());
}
合并两个数组,并去掉重复元素,然后排序(C#)


List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 12, 10 };
List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
var newQuerty = numbers1.Concat(
from n in numbers2
where !numbers1.Contains(n)
select n
).OrderBy(n=>n);
合并两个数组,并去除合并后的重复数据, 并排序

int[] A={1,2,2,3,4,5,6,6,6};
            int[] B={2,2,2,3,7,8,9,5};

List<int> list = new List<int>(A);
            list.AddRange(B);

list.Sort();

//去除重复项
            foreach (int i in list.Distinct<int>())
            {
                Console.WriteLine(i);
            }

C# 取两个数组的相同元素

以往我们都是肯定绞尽脑汁,肯定什么循环,元素大小,什么因素都考虑进去。但是现在采用Linq可以很好的解决这个问题。找出两个或多个数组的相同项。

代码相当简单:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Text;

namespaceTest4_03

{

classProgram

{

staticvoidMain(string[] args)

{

string[] names = {"Adams","Arthur","Buchanan","Tsbuchis","ShCian","FuchsiaLinda","DecheChen","Lotheer","FindLanciCade","SorchLand","JiangZheng","MisiiLoda","Gtod","Dfac","Lama","BakCades","Losangle","ZheWQ","GehengDahaLothi","ToryLandey","DakaLothy","BthLanda","MenNorth","Fith","FoxMain","DontM","Saobba","Del","Sala","Ghero","BhthLaPhda"};

IEnumerable<string> skip = names.Skip(10);

IEnumerable<string> take = names.Take(11);

//取出两个序列中交集部分,按理论应该输出JiangZheng

IEnumerable<string> intersect = skip.Intersect(take);

foreach(varsinintersect)

{

Console.WriteLine(s);

}

Console.ReadKey();

}

}

}

C# 获取两个数组集合的差集,交集

今天在做一个树形选择节点时,遇到一个问题,属性节点是记录了相关的ID值,第一次呢全部对这些ID进行处理,但是接下来再次选择就要分情况了,原先选择的ID如果不在新选择的集合中那么剔除掉,否则,原先ID不传入函数处理,新ID传入函数处理:

比如原来①选择的ID是:1,2,3,4                下次:1,2,3,4,5,   那么这时候5要处理,1,2,3,4维持原样。

②选择ID是:1,3                          下次: 3,4,5           那么这时候4,5 要处理,3 维持原样。1剔除。

③选择ID是:1,2,3,4,5                  下次:3,4,5             那么这时候3,4,5都维持原样,1,2剔除。

④选择ID是:1,2                           下次:3,4,5             那么这时候3,4,5处理,1,2剔除。

简化一下数学模型:

大家发现没其实这就是一个数学的概念,集合的差集,那么我们怎么处理呢? 假设前次选择的集合为A,后次选择为B

得到要处理的很简单:B-A (B与A的差集)就是要处理的集合元素,为什么呢?根据概念可知哈!

那么得到不做处理的怎么办呢? 不要处理的必然是B的子集,那么怎么得到呢?

出来啦既是:B-(B-A)    这是为什么呢? B-A  就是要处理的,而维持原样的就是当然就是:B-(B-A),

那么剔除的集合呢? A-(B-(B-A))

如何用C#表示呢,我这里就不用什么循环之类的了,我用的是NET3.5 那就好办了,用Linq处理:

俺这里特殊点,右键得到的树形集合(lstSource)包含了其他信息,先获取ID集合再说:

var m_ilAllSelect = lstSource.Select(r => r.ID).AsEnumerable();//新选择的列表

///////下面开始处理了

List<int> m_ilNewSelect = m_ilAllSelect.ToList();//新选择列表
List<int> m_ilExcept = m_ilNewSelect.Except(m_mcuids).ToList(); //两者的不同之处
List<int> m_iExceptAfterAndNew = m_ilNewSelect.Except(m_ilExcept).ToList();//新选择列表与差集比较,则是新选择中的旧的

为了简化给大家,这里的A代表旧集合,B代表新集合,这里的集合都是List<int>泛型列表。

那么要处理的就是 B.Except(A), 维持原样的:B( B.Except(A)), 剔除的:A.Except(B( B.Except(A))),

不要问我这个Except方法啥意思?看MSDN吧,google也行啦!

当然我实际的源码比这更细致点,至此解决集合的差集的知识点就这些了!

 

Linq中join & group join & left join 的用法的更多相关文章

  1. 简述Linq中.ToList(), .AsEnumerable(), AsQueryable()的区别和用法

    [TOC] 这3个方法的功能完全不同, 应按照具体业务场景使用. AsQueryable() 先说说什么是 IQueryable IQueryable 是当前的 data provider 返回的类型 ...

  2. EF Linq中的左连接Left Join查询

    linq中的join是inner join内连接,就是当两个表中有一个表对应的数据没有的时候那个关联就不成立. 比如表A B的数据如下 from a in A join b in B on a.BId ...

  3. Linq中的group by多表多字段

    在sql中,如果有group by,那么select的字段只能包含分组内容,或者count.sum.avg这些统计字段. 但在linq里面,是:group 你想要什么字段 by 分组字段 比如: va ...

  4. Linq中的group by多表多字段,Sum求和

    //Line to Sql 写法 var data = (from a in Items group a by new { a.GroupId, a.Id } into b //orderby new ...

  5. linq中的group by

    现有如下需求,要求统计int数组中每个整数的个数: ,,,,,,,,,,,, }; var linq = from item in arrInt group item by item into g// ...

  6. 关于LinQ中“from"前置的原因

    原文地址:http://blog.csdn.net/yuzifen/article/details/6754003 概括来说是:为了IDE的智能感知(Intelisence)功能,(或说为了进行类型推 ...

  7. Linq中的连接(join)

    http://www.cnblogs.com/scottckt/archive/2010/08/11/1797716.html Linq中连接主要有组连接.内连接.左外连接.交叉连接四种.各个用法如下 ...

  8. LINQ中的连接(join)用法示例

    Linq中连接主要有组连接.内连接.左外连接.交叉连接四种.各个用法如下. 1. 组连接 组连接是与分组查询是一样的.即根据分组得到结果. 如下例,根据publisther分组得到结果. 使用组连接的 ...

  9. Linq 中 Join 的用法

    Linq中连接主要有组连接.内连接.左外连接.交叉连接四种.各个用法如下. 注:本文内容主要来自<Linq实战>,本例中用到的对象请见文章底部. 1. 组连接 组连接是与分组查询是一样的. ...

随机推荐

  1. 297 - Quadtrees (UVa)

    Quadtrees A quadtree is a representation format used to encode images. The fundamental idea behind t ...

  2. 设计模式学习--复合模式(Compound Pattern)

    设计模式学习--复合模式(Compound Pattern) 概述 ——————————————————————————————————————————————————— 2013年8月4日<H ...

  3. Java-装饰模式(转)

    装饰模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关 ...

  4. Android 交错 GridView

    原文地址 本文演示在你的 Android 应用程序中显示交错 GridView(Staggered GridView ). 下载 Demo 交错 GridView 交错 GridView 只是具有不等 ...

  5. RHEL7和RHEL6的主要变化

    RHEL7和RHEL6的主要变化   RHEL7 RHEL6 文件系统 XFS EXT4 内核版本 3.10.x-x系列 2.6.x-x系列 内核名称 Maipo Santiago 发布时间 2014 ...

  6. 一键cobbler批量安装脚本

    前几天机房上架180台服务器,太多了,使用了cobbler批量安装,具体的看我上代码,我把配置cobbler的命令给堆积起来,也算是个脚本吧,欢迎拍砖指正,下面我上脚本: #!/bin/bash # ...

  7. Try,Catch,Finally三块中如果有Return是怎么个运行顺序

    今天看一个Java SSH的面试题,题目大概意思是:try.catch中存在return语句,还会执行finally块吗?如果执行,是return先执行还是finally先执行?如果有多个return ...

  8. (转)linux下导入、导出mysql数据库命令

    原文链接:http://www.xiaohuai.com/2902 一.导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径):1.导出数据和表结构:mysqldump -u用 ...

  9. 升级openssl到1.0.1g

    先进行支撑包的安装: # yum install -y zlib   openssl升级步骤: 下载最新版本的openssl源码包 # wget ftp://ftp.openssl.org/sourc ...

  10. 如何修改TextField的Label和EmptyText

    在需求中常常有修改form表单的标签和空文本提示,在渲染后组件有些字符固定下来 除非使用document进行原始修改,通过查询stackflow,我介绍更方便方法 模拟场景:点击ChangeLabel ...