我想以性能为目的进行投影,但是select部分返回匿名类型,因此我无法进行所需的映射。
var jobDegreesQuery = _context.JOBDEGREEs.AsQueryable().Select(d=> new {d.DEGREE_CODE,d.DEGREE_NAME });
if (!String.IsNullOrWhiteSpace(name))
jobDegreesQuery = jobDegreesQuery.Where(c => c.DEGREE_NAME.Contains(name));
var jobDegreeDTOs = jobDegreesQuery
.ToList()
.Select(Mapper.Map<JOBDEGREE, JobDegreeDTO>); //The error
方法'Enumerable.Select(IEnumerable,Func)'的类型参数不能为 从用法推断。尝试显式指定类型参数。
如何进行投影并成功映射到DTO
?
答案 0 :(得分:1)
据我了解,您想将JOBDEGREEs映射到JobDegreeDTO。您首先要选择它作为匿名类型,所以我认为AutoMapper无法映射,因为您给了一个匿名提示。类型。
按如下所示更改您的代码会更好:
RewriteCond %{HTTPS} off
RewriteRule !^page\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NC,NE]
答案 1 :(得分:1)
您的ToList()
的结果是什么?它是一些匿名类的对象的列表,其中包含从JobDegrees
每当要在对象序列上使用Enumerable.Select
时,首先必须命名一个标识符,该标识符代表序列中的一个元素。该标识符是=>
之前的部分。 =>
之后,您将编写代码以使用此输入标识符返回一个对象。
这是一种很难表达的方式:
IEnumerable<Person> myPersons = ...
var firstNames = myPersns.Select(person => person.FirstName);
在person
之前的=>
代表Persons
集合中的一项。因此person
似乎是此标识符的专有名称。
如果您希望使用任何标识符来标识person
,尽管并非所有标识符都可以提高可读性:
var firstNames = myPersns.Select(x => x.FirstName);
在使用LINQ和实体框架时,优良作法是识别具有复数名词的集合和具有单数名词的集合的元素。
在=>
之后,您编写了一些使用此输入person
返回恰好一个对象的代码。在此示例中,{{1}中的FirstName
。
返回您的问题
您的person
的结果是带有ToList
和DegreeCode
的一系列对象。
如果要将序列中的每个对象都转换为另一个对象(这称为投影),则必须在“ =>”之前标识序列中的一个对象。
例如
DegreeName
这里,每个...ToList()
.Select(extractedDegreeData => ...)
都对应于列表中的一个元素。
现在您要如何处理一个这样的extractedDegreeData
?您要返回extractedDegreeData
的返回值。
因此,您的代码应类似于:
Mapper.Map<JOBDEGREE, JobDegreeDTO>(extractedDegreeData)
在构造LINQ查询时,不要使用诸如...ToList()
.Select(extractedDegreeData => Mapper.Map<JOBDEGREE, JobDegreeDTO>(extractedDegreeData));
之类的函数,或者不使用任何不返回ToList
的函数,这会浪费处理能力。如果您在IEnumerable<TResult>
之后放了Select
,该怎么办?如果只需要前两个元素,那么创建1000个元素的完整列表真是浪费!
因此,Take(2)
,ToList
,FirstOrDefault
,Max
之类的函数应始终是linq查询中的最后一个。
最后:Count
是实现dbContext.JobDegrees
的{{1}},因此不需要使用DbSet<JobDegree>
。