我遇到过LINQ问题,希望你能帮我弄清楚。
以下是发生的事情。
IQueryable<LicenseEntity>
个实体。Customer
的字段。它也包含有效数据,因为我使用LicenseEntity加载它。 .Select
将每个LicenseEntity投影到LicenseViewModel。AutoMapper.Mapper.Map
并加载到LicenceViewModel实体中。MapMe()
。当我停在MapMe中的return语句并查看s
参数(原始实体)时,我发现其中的数据没问题,但客户字段现在为空。我认为Select
做了一些我不知道的事情。如何Select
在进行投影时保留原始实体中的所有信息?我们的解决方案无法实现列表,因为它可能非常非常大。我已将下面的测试代码包含在内,非常感谢您的帮助。
// Get the IQueryable<LicenseEntity> list of licenses from the repository.
var list = LicenseRepository.List();
// Convert the IQueryable<LicenseEntity> to an IQueryable<LicenseViewModel>
var vmlist = list.Select(x => MapMe(x, new LicenseViewModel()));
//var vmlist = list.Select(x => AutoMapper.Mapper.Map(x, new LicenseViewModel()));
// This function was used to see the LicenseEntity that was passing into Map().
// I discovered that the entity has all the correct data except for a related
// entity field, which was present in the original LicenseEntity before
public LicenseViewModel MapMe(LicenseEntity s, LicenseViewModel d)
{
return d;
}
以下代码正常工作,但它实现了实体,我们无法做到。
List<LicenseViewModel> vms = new List<LicenseViewModel>();
foreach (var item in list)
{
var vm = AutoMapper.Mapper.Map(item, new LicenseViewModel());
vms.Add(vm);
}
答案 0 :(得分:1)
您已对此LINQ-to-Entities
进行了标记,但未在文中提及基础技术。但问题很可能是由于关联对象的延迟加载造成的。
这是一个适用于我曾经使用过的大多数ORM的设计选择。加载对象时,默认情况下不会加载连接的对象。如果它们在默认情况下被加载,很明显你会快速破坏所有内容
答案是您需要指定要加载的相关对象。在实体框架中,您执行此操作using the Include
method。
因为您正在使用存储库抽象,您可能会发现它比它需要的更难,但是在不知道更多的情况下我无法给出任何建议。这种类型的功能 - 非常基本的东西 - 总是存储库和“工作单元”模式的难度。
答案 1 :(得分:0)
我认为您的映射应该更像:
var vms = Mapper.Map<List<LicenseEntity>, List<LicenseViewModel>>(list);
(即 - 您不需要foreach
循环)。
但不幸的是,我非常怀疑这会解决你的问题,因为我怀疑这也会实现你的实体。
答案 2 :(得分:0)
我找到了将域实体投影到视图模型的解决方案。如果您遇到与我相同的问题,请查看以下链接:
http://lostechies.com/jimmybogard/2011/02/09/autoprojecting-linq-queries/ http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-code
顺便说一句,在一个我的域实体中,我有一个带有一些“计算”属性的部分类...其值是从数据库记录中的其他字段生成的属性。这些不能在域实体中,因为它们会干扰上述解决方案。我把它们移到我的ViewModel类,这是他们真正需要的地方,一切都很好。
希望这些信息有助于......
麦克