Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式
当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据。需要使用Left Join获取数据:
Linq语法如下:
var sg = (from g in dc.sgroup
join gu in dc.sgroupuser on g.gKey equals gu.gKey into l
from lgu in l.DefaultIfEmpty()
select new { g, lgu }).ToList();
Lambda表达式如下:
var sg = dc.sgroup.GroupJoin(dc.sgroupuser, g => g.gKey, gu
=> gu.gKey, (g, gu) => new { g, gu
}).Select(o=>o).ToList() ;
注意:
Linq
与Lambda表达式取出的结果有所不同.Linq取出的结果的记录数与Sql中的Left
Join的结果相同,而Lambda表达式取出的记录数是sgroup表中的记录数,sgroupuser对应的记录是以对象集合存在于结果中
附:
下面是Inner Join:
Linq语法如下:
var sg = (from g in dc.sgroup
join gu in dc.sgroupuser on g.gKey equals
gu.gKey
select new { g, gu }).ToList();
Lambda表达式如下:
var sg = dc.sgroup.Join(dc.sgroupuser, g => g.gKey, gu =>
gu.gKey, (g, gu) => new { g, gu }).Select(o=>o).ToList()
;
注意:
上面最后都用到了ToList()方法 ,
用ToList()是为了一次性将数据取到本地.
egg:例子
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Collections;
namespace fuck
{
public delegate int del(int i);
public delegate bool Mydetext();
class Program
{
//聲明委託變量
public Mydetext mytext;
static void Main(string[] args)
{
#region 例子一
//聲明委託變量
del myDelegate = x => x * x; //lambda表達式也就是匿名委託的原理
//聲明委託變量
del myDelegatetwo = delegate(int x)
{
return x * x;
};
int i = myDelegate(5);
int j = myDelegatetwo(5); //j = 25
Console.WriteLine(i);
Console.WriteLine(j);
#endregion
#region 例子二
//聲明委託變量
if (new Program() { mytext = new Mydetext(delegate() { Console.Write("Hello "); return false; }) }.mytext())
{
Console.Write("Hello ");
}
else
{
Console.WriteLine("World");
}
if (new Func<bool>(() => { Console.Write("Hello "); return false; }).Invoke())
{
Console.Write("Hello ");
}
else
{
Console.WriteLine("World");
}
if (new Program() { mytext = new Mydetext(() => { Console.Write("Hello "); return false; }) }.mytext())
{
Console.Write("Hello ");
}
else
{
Console.WriteLine("World");
}
#endregion
#region 例子三
List<int> ls = new List<int>();
ls.Add(1);
ls.Add(9);
ls.Add(5);
ls.Add(7);
var chaojie = ls.Select((m, index) => new { m, index }).OrderByDescending(n => n.m).Take(1);
//try 下面的和上面的效果是一樣子的 //這裡是這樣子理解的聲明一個匿名委託 return new { m, index };可以理解為查詢出m,和index
var chaojietwo = ls.Select(delegate(int m,int index) { return new { index, m }; }).OrderByDescending(n => n.m).Take(1);
//在這裡其實就是ls.Select(new {}) 和例子四很像 delegate(int m,int index)的參數順序決定是值,還是索引/第一個是值,第二個是索引
foreach (var w in chaojietwo)
{
Console.WriteLine("索引" + w.index + ",值" + w.m);
}
#endregion
#region 例子四
Dictionary<int,string> alt=new Dictionary<int,string>();
alt.Add(1,"一");
alt.Add(9,"九");
alt.Add(5,"五");
alt.Add(7,"七");
var query = from qy in alt
select new {qy.Key,qy.Value };
foreach (var q in alt)
{
Console.WriteLine("鍵" + q.Key + ",值" +q.Value);
}
#endregion
#region 例子五
List<double> list = new List<double>();
list.Add(2.55);
list.Add(4.45);
list.Add(12.35);
list.Add(18.35);
list.Add(17.35);
list.Add(19.35);
list.Add(6.355);
list.Add(7.95);
list.Add(4.35);
var v = list.Select((m, index) => new { m, index }).OrderByDescending(n => n.m).Take(1);
foreach (var w in v)
{
Console.WriteLine("索引"+w.index+",值"+w.m);
}
List<double> list2 = new List<double>();
list2.Add(2.55);
list2.Add(4.45);
list2.Add(18.35);
list2.Add(17.35);
list2.Add(19.35);
list2.Add(6.355);
list2.Add(7.95);
list2.Add(4.35);
//其實這兩個是一個樣子的
//var lt2 = list2.Where(a=>a==2.55);
//lt2也可以寫成
var lt2 = list2.Where(delegate(double ls11) { return ls11==2.55;});
// var lt3 = (from z in list2
// select z).Where(y=>y>3);
//其實下面這個和上面這個也是一樣子的
var lt3 = (from z in list2
select z).Where(delegate(double y) { return y > 3; });
Console.WriteLine("條件一");
foreach (var w in lt2)
{
Console.WriteLine("值"+w);
}
Console.WriteLine("條件二");
foreach (var w in lt3)
{
Console.WriteLine("值" + w);
}
#endregion
Console.ReadKey();
}
}
}
效果
在公司的讲课
關於linq的最簡單例子
例子1
var ss = from r in Am_recProScheme
select r;
string sssql = "select * from Am_recProScheme";
例子2
var ss = from r in Am_recProScheme
where r.rpId > 10
select r;
string sssql = "select * from Am_recProScheme where rpid>10";
關於linq的最簡單例子
簡單函數count min max sum 的應用
例子3 var ss = (from r in Am_recProScheme
select r).Max(p=>p.rpId);
var ss = (from r in Am_recProScheme
select r).Sum(p=>p.rpId);
var ss = (from r in Am_recProScheme
select r).Min(p=>p.rpId);
string sssql = "select Max(reId) from Am_recProScheme";
string sssql = "select Sum(reId) from Am_recProScheme";
string sssql = "select Min(reId) from Am_recProScheme";
簡單order by應用
例子4
var ss = from r in Am_recProScheme
where r.rpId > 10
order by r.reId desc
select r;
string sssql = "select * from Am_recProScheme where rpid>10 order by rpId desc"
關於linq的最簡單例子
簡單函數like,in的應用
例子3 var ss = from r in Am_recProScheme
where r.SortsText.Contains("張");
select r;
string sssql = "select * from Am_recProScheme where r.SortsText like ‘%張%‘";
var ss = from r in Am_recProScheme
where (new int[]{24,25,26}).Contains(r.rpId);
select r;
string sssql = "select * from Am_recProScheme where r.rpId in (24,25,26)";
簡單查詢出某幾列應用
例子4
var ss = from r in Am_recProScheme
where r.rpId > 10
order by r.rpId desc
select new {r.rpId,r.rpName};
string sssql = "select rpId,rpName from Am_recProScheme where rpid>10 order by rpId desc"
關於linq的最簡單例子
簡單函數連表查詢的應用
我们在做SQL查询的时候经常会用到Inner Join,Left Join,连接方式的概念方面我想也不用给予太多解释,
我们今天的重点是让大家熟悉LINQ是如何使用Join来实现常用的表连接的。
创建测试用类:
class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Origin { get; set; }
}
class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public List<Product> Products { get; set; }
}
我们用以下例子来熟悉 Join 关键字的用法。
1.Inner Join:
CreateEntities();
var query = from c in customers
join o in orders on c.CustomerId equals o.CustomerId
where o.OrderId == 2
select c;
foreach (var customer in query)
{
Console.WriteLine("Id:{0}, Name:{1}", customer.CustomerId, customer.Name);
}
运行结果:
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的概念不太了解,没关系让我们通过例子来认识它:
CreateEntities();
var query = from c in customers
join o in orders on c.CustomerId equals o.CustomerId into os
select new { c, os };
foreach (var item in query)
{
Console.WriteLine("Customer Id:{0}, Name:{1}", item.c.CustomerId, item.c.Name);
foreach (var o in item.os)
{
Console.WriteLine("--Order Id:{0}", o.OrderId);
}
}
结果:
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里怎么实现它:
CreateEntities();
var query = from c in customers
join o in orders on c.CustomerId equals o.CustomerId into os
from o2 in os.DefaultIfEmpty(
new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })
select new { c, o2 };
foreach (var item in query)
{
Console.WriteLine("Customer Id:{0}, Name:{1}--Order Id:{0}",
item.c.CustomerId, item.o2.OrderId);
}
结果:
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查询表达式中用的不是很多。
2015-03-25
以下是linq連表的例子 相當於左連接
var ls = (from i in gt.vendor_login
join j in gt.vendor on i.vendor_id equals j.vendor_id
into AAA
from j in AAA.DefaultIfEmpty()
select new myclass { AA = i.vendor_id, BB = j != null ? j.vendor_name_full : null }).ToList();
// 相當於內連接
var ls = (from i in gt.vendor_login
fromj in gt.vendor on i.vendor_id equals j.vendor_id
select new myclass { AA = i.vendor_id, BB = j != null ? j.vendor_name_full : null }).ToList();
//類似於內連接
ls = (from i in gt.vendor_login
from j in gt.vendor
where i.vendor_id==j.vendor_id
select new { i, j }).ToList().ConvertAll<VendorLoginQuery>(w => new VendorLoginQuery { login_id = w.i.login_id, vendor_id = w.i.vendor_id, login_ipfrom = w.i.login_ipfrom, login_createdate = w.i.login_createdate, vendor_name_full = w.j.vendor_name_full }).Skip(10).Take(100).ToList();