实例:
using (var _TaoXueDBEntities = new TaoXueDBEntities()) { // linq语句的形式联表: 不过不能实现动态条件查询:(
//var v = from l in _TaoXueDBEntities.UserAccount
// join t in _TaoXueDBEntities.TeacherInfo on l.UIN equals t.UIN
// where l.UIN==1
// orderby t.CreateDateTime descending
// select new TeacherAccountInfo
// {
// BaseUserAccount = l,
// teacherInfo = t
// };
实现动态条件查询:)
Expression<Func<TeacherAccountInfo, bool>> exp = c => c.BaseUserAccount.UIN > 0;
if(teacherSearch!=null)
{
if(!string.IsNullOrWhiteSpace(teacherSearch.TeacherName))
{
exp = exp.AndAlso(l => l.BaseUserAccount.Name.Contains(teacherSearch.TeacherName));
}
if(!string.IsNullOrWhiteSpace(teacherSearch.TeachingExperience))
{
exp = exp.AndAlso(l => l.teacherInfo.Experience.Contains(teacherSearch.TeachingExperience));
}
}
var v = _TaoXueDBEntities.UserAccount.Join(_TaoXueDBEntities.TeacherInfo, u => u.UIN, t => t.UIN,
(u, t) =>
new TeacherAccountInfo { teacherInfo = t, BaseUserAccount = u }).Where(exp).OrderByDescending(l=>l.teacherInfo.UIN);
var pageList = new PageList<TeacherAccountInfo>(v, page, pageSize);
return pageList;
}
然后3个联合的时候:就出现“/”应用程序中的服务器错误:
|
在单个 LINQ to Entities 查询中的两个结构上不兼容的初始化过程中出现类型“Taoxue.Entities.DTO.TeacherAccountInfo”。类型可以在同一查询中的两个位置初始化,但前提是在这两个位置设置了相同的属性,且这些属性是以相同的顺序设置的。
代码改为:
var v = _TaoXueDBEntities.UserAccount.Join(_TaoXueDBEntities.TeacherInfo, u => u.UIN, t => t.UIN, (u, t) => new { teacherInfo = t, BaseUserAccount = u }).Join(_TaoXueDBEntities.Lesson, ti => ti.teacherInfo.UIN, l => l.TeacherUIN, (ti, l) => new TeacherAccountInfo { IsTeachingLesson = l, teacherInfo = ti.teacherInfo, BaseUserAccount= ti.BaseUserAccount }) .Where(exp).OrderByDescending(l => l.teacherInfo.UIN);
OK~
转: 使用方法语法的复杂查询(续例)
// 使用相同数据创建客户列表 Output: |
在示例13-3中,查询使用了查询的语法:
var result = |
它被翻译为以下方法的语法:
var result = customers.Join(addresses, |
lambda表达式需要一些时间来适应。以OrderBy子句开始;你可以把它读作"通过以下方式来排序:对于每一个客户地址,获得客户的姓氏。"你把整个语句读作:"从客户开始,和地址通过以下方式连接:连接客户的名字和姓氏,获取地址的名称,对两者进行连接,然后对于每一个结果记录创建一个客户地址对象,这个对象的客户和地址由取出来的客户和地址赋值;然后首先通过每个客户的姓氏排序,再接着根据每个地址的街道名称按降序排列。"
主要的数据源即客户集合,仍然是主要的目标对象。扩展方法Join()作用于它来执行连接操作。它的第一个参数是第二个数据源地址。接下来的两个参数是每个数据源的连接条件域。最后一个参数是连接条件的结果,实际上是查询的选择子句。
查询表达式的OrderBy子句表明你想将客户姓氏按升序排列,然后将它们的街道地址按降序排列。在方法语法中必须通过使用OrderBy和ThenBy方法指明这个顺序。
也可以只调用一系列的OrderBy方法,但是这些方法必须逆序调用。也就是说你必须在查询的OrderBy序列中首先对最后一个域调用这个方法,最后才对第一个域调用这个方法。在本例中,你须要首先调用对街道的排序,然后才能调用对名称的排序:
var result = customers.Join(addresses, |
从结果可以看出,两个例子的输出是一样的。因此你可以根据自己的喜好选择其中一个。
提示:Ian Griffiths,地球上最聪明的C#程序员之一,(他的blog在IanG On Tap上,(http://www.interact-sw.co.uk/iangblog/)阐述了以下的观点,我也将会在第15章演示这个观点, 但是我想在这里先表明:"你可以在许多不同的源上使用完全相同的这两个语法,但是行为并不总是相同的。一个lambda表达式的意义随着传给它的函数的原型不同而不同。在这些例子中,它是委托的一个简洁的语法。但是如果你对一个SQL数据源使用相同的查询格式,lambda表达式将会被转变为另外的东西。"
所有的LINQ扩展方法--连接(Join)、选择(Select)、Where,以及其他--具有多种实现,每个实现面向不同的目标类型。这里我们学习的是在IEnumerable上操作的方法。与在IQueryable上操作的方法有微妙的不同。它们接受表达式而不是接受连接、映射、Where及其他子句的委托。这些是非常神奇的技术,使得C#源代码能够转换为相应的SQL查询。