2013-07-25 157 views
3

我在將通過存儲過程查詢的搜索結果映射到我的EF實體時遇到了一些麻煩。我正在使用數據庫第一種方法。將存儲過程結果映射到實體框架中的實體5

我可以很容易地使用DbContext.Database.SqlQuery<T>檢索簡單的實體,只要我的存儲過程返回適當的列名稱,這個工作並沒有問題。然而我的問題是我需要加載相關的實體以及搜索結果。

這就是我的工作:從DbSet<Product>獲取數據時

// Product.cs 
public class Product 
{ 
    public int ProductId { get; set; } 
    public int CategoryId { get; set; } 
    public int BrandId { get; set; } 

    public virtual Category Category { get; set; } 
    public virtual Brand Brand { get; set; } 
} 

// Category.cs 
public class Category { 
    public int CategoryId { get; set; } 
    ... 
    more properties 
} 

// Brand.cs 
public class Brand { 
    public int BrandId { get; set; } 
    ... 
    more properties 
} 

一切的偉大工程,導航性能變懶加載預期。

會有一種方式從存儲過程中提取所有需要的數據:我的相關實體將被正確填充(即,是否需要以某種特定方式命名我的列)?

我也試驗過第二種方法,在這裏我簡單地從存儲過程中拉出List<int>,ProductId,然後使用Linq查詢再次訪問數據庫以拉取實體。

List<int> results = unitOfWork.SqlQuery<int>(
    @"EXECUTE dbo.SomeStoredProcedure @Keyword", 
    new SqlParameter("Keyword", keyword) 
).ToList(); 

List<Product> products = unitOfWork.ProductRepository.Get(
    filter: q => results.Contains(q.ProductId) 
).ToList(); 

這種方法出現了兩個問題:兩次到數據庫和某處丟失命令。我可以忍受的第一個問題,這是一個低流量的應用程序,我並不擔心額外的數據庫之旅。

第二個是一個更大的問題,雖然。基於存儲過程中的某個搜索值排序,結果將按初始查詢中的正確順序進行提取。然後,這個順序在第二個查詢中丟失,留給我一個隨機排列的結果集,並且沒有辦法(我可以看到)將其排序。

任何想法?

+0

您是否曾嘗試導入存儲過程作爲EDMX中的函數?您可以設置返回類型並將存儲過程列映射到返回類型屬性 – James

+0

@James我沒有。我正在使用POCO,並且在我的項目中沒有.edmx文件。我可以創建.edmx並只映射存儲過程嗎? – dom

+0

你可以,如果你這樣做,你可以使用它來代替你的'DbContext',雖然它做了同樣的事情,並增加了功能。 – James

回答

0

我無法使用.edmx映射工作,所以我最終堅持使用第二種方法,並使用一種非常黑客的方式讓我的結果按照他們應該的方式排序。

我拉我的實體有兩個查詢,在原來的問題(第一個列表是按照正確的順序)中提到:

public class SearchViewModel : BaseViewModel 
{ 
    public SearchViewModel() 
    { 
     this.Results = new List<int>(); 
     this.Products = new List<Product>(); 
    } 

    public string Keyword { get; set; } 
    public List<int> Results { get; set; } 
    public List<Product> Products { get; set; } 
} 

List<int> results = unitOfWork.SqlQuery<int>(
    @"EXECUTE dbo.SomeStoredProcedure @Keyword", 
    new SqlParameter("Keyword", keyword) 
).ToList(); 

List<Product> products = unitOfWork.ProductRepository.Get(
    filter: q => results.Contains(q.ProductId) 
).ToList(); 

我使用視圖模型兩個列表傳遞到我的觀點

然後在視圖級別而不是循環List<Product>,我遍歷結果列表。

<ul class="products medium"> 
    @foreach(int productId in Model.Results){ 
     var product = Model.Products.FirstOrDefault(p => p.ProductId == productId); 
     <li> 
      ... 
      display content 
     </li> 
    } 
</ul> 

感覺骯髒和黑客,但它現在必須做。當我找到一個不需要使用.edmx文件的更好的解決方案時,也許我會回到它。

+0

你想使用EDMX – meda

+0

@meda如何做到這一點當然,它會派上用場,當我再次遇到類似的情況。 – dom

相關問題