2010-11-08 137 views
1

我正在使用ASP.NET MVC2与EF4。我需要为我的两个类PersonP和AddressP创建POCO,这些类对应于它们的EF4'复杂'类(其中包括导航属性和OnPropertyChanged())等。只映射PersonP本身工作正常,但PersonP包含AddressP(外键) - 我如何使用IQueryable表达式映射它?IQueryable实体框架POCO映射

这里是我试过:

class AddressP 
{ 
int Id { get; set; } 
string Street { get; set; } 
} 

class PersonP 
{ 
int Id { get; set; } 
string FirstName { get; set; } 
AddressP Address { get; set; } 
} 

IQueryable<PersonP> persons = _repo.QueryAll() 
    .Include("Address") 
    .Select(p => new PersonP 
{ 
Id = p.Id, 
FirstName = p.FirstName, 
//Address = p.Address <-- I'd like to do this, but p.Address is Address, not AddressP 
//Address = (p.Address == null) ? null : 
//new AddressP <-- does not work; can't use CLR object in LINQ runtime expression 
//{ 
// Id = p.Address.Id, 
// Street = p.Address.Street 
//} 
}); 
  1. 没有.Include("Address")我不会检索地址表什么这是正确的?

  2. 如何使用上面的Select()声明将Address映射到AddressP里面PersonP

谢谢。

回答

1
  1. 这是正确的,如果你禁用延迟加载或您的对象上下文已被设置,并且不能用于获取延迟加载工作。

  2. 是的,它不会工作,因为首先你需要执行你的查询,然后开始映射它,否则你的映射逻辑将被视为在数据库中运行,因此是例外。
    像这样将工作:
// First we execute the query: 
IQueryable<PersonP> persons = _repo.QueryAll().Include("Address").ToList(); 

// Now we have a IEnumerable and we can safely do the mappings: 
persons.Select(p => new PersonP 
{ 
    Id = p.Id, 
    FirstName = p.FirstName, 
    Address = (p.Address == null) ? null : new AddressP() 
    { 
     Id = p.Address.Id, 
     Street = p.Address.Street 
    } 
}).ToList(); 

虽然这种解决方案会做的伎俩,但如果目的是让POCO类,你应该考虑采取EF4.0 POCO支持优势,并直接使用POCO类用EF代替之后的映射。一个好的开始将是这个演练:
Walkthrough: POCO Template for the Entity Framework

+0

谢谢你的回应,这正是我所期待的。不幸的是,我必须将它保留为IQueryable,因为我必须使用第三方方法应用筛选/排序/分组,并且人员/地址存储库可能非常庞大 - 所以我必须在执行实际查询之前执行此操作。我将研究POCO EF4支持 - 你会推荐NHibernate解决方案吗? – John 2010-11-08 05:11:23

+0

我对NHibernate没有任何经验,但我不认为它会有任何不同。你也可以看看AsQueryable,看看你是否可以使用它,但我仍然认为POCO是在这种情况下走的路。 – 2010-11-08 14:19:23