代码:
public class Person{public int ID { get; set; }public string Name { get; set; }public int Age { get; set; } }public class Dog{public int ID { get; set; }public string Name { get; set; }public int PersonID { get; set; }}public class DogClothes{public int ID { get; set; }public string Name { get; set; }public int DogID { get; set; }}public class ActionPerson{ public ListGetPersons(){List list = new List ();for (var i = 0; i < 10; i++){Person p = new Person {ID=i+1, Name = "hongda" + (i + 1), Age = 26 + i };list.Add(p);}return list;}public List GetDogs(){List dogs = new List ();for (var i = 1; i < 15; i++){Dog dog = new Dog { ID = i, Name = "dogs" + i, PersonID = (i %5)+1 };dogs.Add(dog);}return dogs;}public List GetDogClotheses(){List DogClothes = new List ();for (var i = 1; i < 13; i++){DogClothes clothes = new DogClothes() { ID = i, Name = "DogClothes" + i, DogID = (i % 4) + 2 };DogClothes.Add(clothes);}return DogClothes;}public void Show (List list){foreach (var l in list){ShowObj(l);}}public void ShowObj (T data){Type t = data.GetType();PropertyInfo[] infos = t.GetProperties();StringBuilder strBuilder = new StringBuilder();foreach (var p in infos){object value = p.GetValue(data, null);string name = p.Name.ToString();strBuilder.Append(name + ":" + value + ",");}Console.WriteLine(strBuilder.ToString());}}
对list操作
上面的代码可以不看,反正就是一些临时用的数据
ActionPerson ap = new ActionPerson();Listlist = ap.GetPersons();ap.Show(list);Console.WriteLine("========================================");List dogs = ap.GetDogs();ap.Show(dogs);Console.WriteLine("========================================");
上面的是list,下面的是dogs
ap(dogClothes);
1.取有狗的人
var list2 = from a in list from b in dogs where a.ID == b.PersonID select a;ap.Show(list2.ToList());Console.WriteLine("========================================");ap.Show(list2.Distinct().ToList());Console.WriteLine("========================================");
发现,自连接就是左表一条条数据与右表一条条数据交叉,取得符合条件的(a.ID==b.PersonID),再取得需要的字段(a),不会自动合并。
看这个就清楚了
var list4 = from a in list from b in dogs where a.ID == b.PersonID select new { a.ID, a.Name, a.Age, DogsID = b.ID, DogsName = b.Name };ap.Show(list4.ToList());
这样上面的就不要区分(distinct)了,之后再取需要的字段
2.join
var list2 = from a in list join b in dogs on a.ID equals b.PersonID into c select new { a.ID, a.Name, a.Age,Count=c.Count() };ap.Show(list2.ToList());
在上面这种into一个对象时,会发现b不能够调用了,a还是可以使用的,当然新形成的对象c也可以,c有一些特殊的属性,例如count
var list2 = from a in list join b in dogs on a.ID equals b.PersonID select new { a.ID, a.Name, a.Age, DogsID = b.ID, DogsName = b.Name, b.PersonID };
var list2 = from a in list join b in dogs on a.ID equals b.PersonID select new { a.ID, a.Name, a.Age };ap.Show(list2.ToList());
跟自连接一样
LINQ TO SQL中的join,如果带有into,可以提前对表进行过滤条件的操作,而不用等到两表进行迪卡尔积产生虚似表后再进行join on的条件过滤。
关于left join
var list2 = from a in listjoin b in dogs on a.ID equals b.PersonID into cfrom o in c.DefaultIfEmpty()select new{a.ID,a.Name,a.Age,DogsID =o==null?0: o.ID,DogsName = o == null ? "" : o.Name,PersonID=o==null?0:o.PersonID };
在数据库中就不需要这么复杂,这里list中要考虑右侧可能为空,
数据库查询就不需要。
多查询
static void Main(string[] args){ActionPerson ap = new ActionPerson();Listlist = ap.GetPersons();List dogs = ap.GetDogs();List dogClotheses = ap.GetDogClotheses();var result = from a in listjoin b in dogson a.ID equals b.PersonIDjoin c in dogClotheseson b.ID equals c.DogIDselect new{a.ID ,a.Name ,a.Age,DogID=b.ID ,DogName=b.Name,b.PersonID ,DogClothesID=c.ID,DogClothesName=c.Name ,DogID2=c.DogID };ap.Show(result.ToList ()); Console.ReadLine();}
var result = from a in listfrom b in dogsfrom c in dogClotheseswhere a.ID == b.PersonID && b.ID == c.DogIDselect new{a.ID,a.Name,a.Age,DogID = b.ID,DogName = b.Name,b.PersonID,DogClothesID = c.ID,DogClothesName = c.Name,DogID2 = c.DogID };
结果上同
http://developer.51cto.com/art/200909/152189.htm
http://www.cnblogs.com/ASPNET2008/archive/2008/12/21/1358152.html