我需要知道如何将AutoMapper从8.0升级到9.0。我所有的查询通常如下所示。我查询数据的一个子集,并创建一个DTO对象,以最少的数据发送给客户端。我不将实体框架与导航属性或集合一起使用,因为可管理性和组织变得很丑陋。取而代之的是,我使用LINQ根据需要以最小的占用空间连接数据,从而简化了数据访问。这是一个例子。
public class ClassificationCourseModel {
public DateTime? PassedDate { get; set; }
public String Title { get; set; }
public String Status { get; set; }
}
public class EmployeeClassificationModel
{
[Key] public int Id { get; set; }
public string Description { get; set; }
public Boolean HasCourses { get; set; }
public Boolean IsCurrent { get; set; }
public List<ClassificationCourseModel> CompleteCourses { get; set; }
public List<ClassificationCourseModel> IncompleteCourses { get; set; }
}
该查询只是对两组数据的联接,以返回给定公司,员工和分类的单个分类。
var courseData =
from crs in _database.ClassificationCourses
where crs.EmployeeId == employeeId
where crs.CompanyId == companyId
where crs.Id == siteEntry.CompanyClassificationId
select crs;
var classificationData = (
from r in _database.EmployeeClassifications
where r.EmployeeId == employeeId
where r.CompanyId == companyId
where r.CompanyClassificationId == siteEntry.CompanyClassificationId
let courses = courseData.Where(c => c.Id == r.CompanyClassificationId)
select new
{
r.Id,
r.Description,
r.IsCurrent,
HasCourses = courseData.Any(),
CompleteCourses = from crs in courses where crs.Completed select crs,
IncompleteCourses = from crs in courses where !crs.Completed select crs
}
).ProjectTo<EmployeeClassificationModel>(_mapper.ConfigurationProvider);
AutoMapper准则(这些似乎是常识设计原则)
我必须修改此帖子,因为我所做的假设是不正确的。我相信,如果不先将它们带入内存,就无法从EntityFramework LINQ查询中<< [选择新POCO。这个假设是通过获得以下异常而产生的:
An exception of type 'System.NotSupportedException' occurred in
EntityFramework.SqlServer.dll but was not handled in user code.
Additional information: The entity or complex type 'xxx' cannot be constructed
in a LINQ to Entities query.
我的答案是创建一个匿名类型,并使用AutoMapper的ProjectTo无缝处理投影。我没有意识到的部分是我错过了一个事实,即POCO实际上与使用的LINQ查询兼容。似乎不支持EF映射类型,并且肯定地,任何调用或公开任何.NET调用的类也会抛出System.NotSupportedException。select new POCO
就是说,尽管我对AutoMapper的使用有所担心,但仍有可行的用例。我只是要保持谨慎,因为AM将类型的定义与类型本身分开,并且如果没有得到适当的尊重,很容易失控。
select new EmployeeClassificationModel
select new ClassificationCourseModel // for both lists
删除行ProjectTo()是实现我认为CreateMissingTypeMaps和ProjectTo()负责的结果的正确方法。我不得不“拿L!”并接受Lucian Bargaoanu给出了正确的答复,即使我的假设让我相信相反的情况。
var courseData =
from crs in _database.ClassificationCourses
where crs.EmployeeId == employeeId
where crs.CompanyId == companyId
where crs.Id == siteEntry.CompanyClassificationId
select crs;
var classification =
from r in _database.EmployeeClassifications
where r.EmployeeId == employeeId
where r.CompanyId == companyId
where r.CompanyClassificationId == siteEntry.CompanyClassificationId
let courses = courseData.Where(c => c.Id == r.CompanyClassificationId)
select new EmployeeClassificationModel
{
Id = r.Id,
Description = r.Description,
IsCurrent = r.IsCurrent,
HasCourses = courseData.Any(),
CompleteCourses =
from crs in courses
where crs.Completed
select new ClassificationCourseModel
{
Title = crs.Title,
PassedDate = crs.PassedDate,
Status = crs.Status
},
IncompleteCourses =
from crs in courses
where !crs.Completed
select new ClassificationCourseModel
{
Title = crs.Title,
PassedDate = crs.PassedDate,
Status = crs.Status
}
};
DTO对象的唯一区别在于,集合已更改为IQueryable。那时,与匿名对象相同,可以在调试器中检查查询后面的SQL。