Lambda表达式使用方法语法的复杂查询: join (在单个 LINQ to Entities 查询中的两个结构上不兼容的初始化过程中出现类型)

实例:

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个联合的时候:就出现“/”应用程序中的服务器错误:


 
行 176:        行 177:        public Taoxue.Entities.PageList<Taoxue.Entities.DTO.TeacherAccountInfo> GetTeacherAccountInfoList(Taoxue.Entities.DTO.TeacherSearch teacherSearch, int page, int pageSize) {行 178:    
        var v = _TaoXueDBEntities.UserAccount.Join(_TaoXueDBEntities.TeacherInfo, u => u.UIN, t => t.UIN,
                                                           (u, t) =>
                                                           new TeacherAccountInfo
                                                           {
                                                               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);
  }

在单个 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~

转: 使用方法语法的复杂查询(续例)

        // 使用相同数据创建客户列表
private static List<Address> CreateAddressList()
{
// 和示例13-3相同
}
}
}

Output:
Janet Gates
Email:   janet1@adventure-works.com
Address: 800 Interchange Blvd., Austin
Janet Gates
Email:   janet1@adventure-works.com
Address: 165 North Main, Austin
Orlando Gee
Email:   orlando0@adventure-works.com
Address: 2251 Elliot Avenue, Seattle
Keith Harris
Email:   keith0@adventure-works.com
Address: 7943 Walnut Ave, Renton
Keith Harris
Email:   keith0@adventure-works.com
Address: 3207 S Grady Way, Renton

在示例13-3中,查询使用了查询的语法:

var result =
from   customer in customers
join address in addresses on
string.Format("{0} {1}", customer.FirstName, customer.LastName)
equals address.Name
orderby customer.LastName, address.Street descending
select new { Customer = customer, Address = address.Street };

它被翻译为以下方法的语法:

var result = customers.Join(addresses,
customer => string.Format("{0} {1}",
customer.FirstName,
customer.LastName),
address => address.Name,
(customer, address) => new { Customer =
customer, Address = address })
.OrderBy(ca => ca.Customer.LastName)
.ThenByDescending(ca => ca.Address.Street);

lambda表达式需要一些时间来适应。以OrderBy子句开始;你可以把它读作"通过以下方式来排序:对于每一个客户地址,获得客户的姓氏。"你把整个语句读作:"从客户开始,和地址通过以下方式连接:连接客户的名字和姓氏,获取地址的名称,对两者进行连接,然后对于每一个结果记录创建一个客户地址对象,这个对象的客户和地址由取出来的客户和地址赋值;然后首先通过每个客户的姓氏排序,再接着根据每个地址的街道名称按降序排列。"

主要的数据源即客户集合,仍然是主要的目标对象。扩展方法Join()作用于它来执行连接操作。它的第一个参数是第二个数据源地址。接下来的两个参数是每个数据源的连接条件域。最后一个参数是连接条件的结果,实际上是查询的选择子句。

查询表达式的OrderBy子句表明你想将客户姓氏按升序排列,然后将它们的街道地址按降序排列。在方法语法中必须通过使用OrderBy和ThenBy方法指明这个顺序。

也可以只调用一系列的OrderBy方法,但是这些方法必须逆序调用。也就是说你必须在查询的OrderBy序列中首先对最后一个域调用这个方法,最后才对第一个域调用这个方法。在本例中,你须要首先调用对街道的排序,然后才能调用对名称的排序:

var result = customers.Join(addresses,
customer => string.Format("{0} {1}", customer.FirstName,
customer.LastName),
address => address.Name,
(customer, address) => new { Customer =
customer, Address = address })
.OrderByDescending(ca => ca.Address.Street)
.OrderBy(ca => ca.Customer.LastName);


从结果可以看出,两个例子的输出是一样的。因此你可以根据自己的喜好选择其中一个。

提示: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查询。

原文地址:https://www.cnblogs.com/dudu837/p/1870231.html