2010-11-08 208 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