2016-09-08 57 views
1

我正在努力解決上述錯誤。我在這裏發現了不同的答案(堆棧溢出),但沒有一個能夠解決與錯誤有關的問題。實體框架已經有一個打開的DataReader與這個命令相關聯,必須先關閉

我只是在我的ConnectionString中啓用MARS,但沒有成功。

我有一類產品

public class Product 
{ 
    public Product() 
    { 
     this.Additives = new HashSet<Additive>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } // refrigerante 
    public string CommercialName { get; set; } // nome popular, ex: fanta laranja 
    public string Brand { get; set; } // marca, ex: Coca-cola 
    public string Details { get; set; } // composicao, ingredientes 
    public HalalState HalalState { get; set; } // estado: halal, haram ou desconhecido 
    public DateTime? LastUpdate { get; set; } // date e hora do registo 

    public virtual ICollection<Additive> Additives { get; set; } // aditivos 
    public int ProviderID { get; set; } 
} 

}

和類添加劑在產品中佔添加劑

using System; 
using System.Collections.Generic; 

namespace Teknowhow.EatHalal.Core.Models 
{ 
    public class Additive 
    { 
     public Additive() 
     { 
      this.Products = new HashSet<Product>(); 
     } 

     public int Id { get; set; } 
     public string Key { get; set; } // codigo ex: E130 
     public string NamePT { get; set; } // nome ex: Acido ascorbico (Vitamina C) em portugues 
     public string NameEN { get; set; } // nome ex: Acido ascorbico (Vitamina C) em inglês 
     public string Details { get; set; } // detalhes sobre o aditivo, incluindo. 
     public HalalState HalalState; // estado: halal, haram ou desconhecido 
     public DateTime? LastUpdate { get; set; } // date e hora do registo 

     public virtual ICollection<Product> Products { get; set;} 
    } 
} 

我在寫代碼來實現對ProductRepository的方法,以用特定的添加劑獲得產品。

public ICollection<Product> GetProductsByAdditive(string key) 
{ 
    var products = context.Products; 
    var productsAdditives = new List<Product>(); 

    foreach (var p in products) 
    { 
     var additives = p.Additives; 

     foreach (var a in additives) 
     { 
      if (a.Key.Equals(key)) 
       productsAdditives.Add(p); 

     } 
    } 

    return productsAdditives.ToList(); 
    //TODO: um Metodo úinico que permite pesquisa por nome em PT e EN e codigo 

} 

錯誤的第一個foreach循環後出現完全相同,在此聲明:

var additives = p.Additives; 

PS:我使用的是EF 6. 我疊!請幫忙!

我的繼承人連接

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
     <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    </configSections> 
    <connectionStrings> 
    <add name="EatHalal" 
     providerName="System.Data.SqlClient" 
     connectionString="Server=192.168.1.150;Database=EatHalal;User Id=user;Password=password;MultipleActiveResultSets=true;" 
      /> 
    </connectionStrings> 
</configuration> 
+0

你能顯示你的連接字符串嗎? – Sampath

+0

我編輯了我的帖子並添加了連接。 – elmodai

回答

2
context.Products.Where(x=>x.Additives.Any(y=>y.Key==key)).ToList(); 

因爲你懶加載的添加劑,而itterating在產品代碼失敗......

但itteration本身是廢話...如果你想在數據庫中搜索某些東西,讓數據庫通過給它搜索某些東西來做它的工作,而不是告訴它給你所有的東西,然後整理出你想要的東西......

想象是否會有幾百萬元的產品在你的表...

你會加載所有產品都要經過他們的年齡......

看看LINQ

看看。其中()

看看。選擇()

熟悉lambda表達式

+0

我試過這段代碼,但是key是一個字符串,而Contains接收一個Additive對象作爲參數,那麼我得到一個編譯錯誤。 但無論如何,我會提高我對lambda表達的理解。我很欣賞你的方法。謝謝! – elmodai

+1

啊...我忽略了添加劑的關鍵屬性...查看編輯 – DarkSquirrel42

5

你可以嘗試如下所示。

注意:你必須先把數據帶上,然後做映射,你不會有這個問題。

原因:當通過查詢(IQueryable)的結果迭代,你會觸發lazy loading爲iteration.In換句話說上有單個連接執行多個數據檢索命令裏面加載的實體。

  foreach (var p in products.ToList()) 
      { 
       var additives = p.Additives.ToList(); 

       foreach (var a in additives) 
       { 
        if (a.Key.Equals(key)) 
        { 
         productsAdditives.Add(p); 
        } 
       } 
      } 
+0

謝謝@Sampath。有用。你能解釋一下爲什麼它有效嗎? – elmodai

+0

你有沒有得到原因或什麼?仍不清楚? – Sampath

+0

是的。延遲加載導致這一點。因爲我有虛擬屬性。 – elmodai

1

準確地說,通過一個IQueryable迭代採用開放DataReader的(所以你可以不讀所有的產品從數據庫中停止迭代)。如果您延遲加載添加劑,則EF使用相同的連接來檢索添加劑,從而導致ADO錯誤。

在這種情況下,您可以像使用其他答案中建議的那樣使用ToList讀取所有產品,或使用Include(p => p.Additives)來快速加載數據。

在特定情況下,最好的辦法是通過添加劑來篩選產品,讓你的功能應該是

public ICollection<Product> GetProductsByAdditive(string key) 
{ 
    return context.Products.Where(p => p.Additives.Select(a => a.Key).Contains(key)).ToList(); 
} 
+0

說明有道理。謝謝!我採用了這種方法。 – elmodai

1

您應該能夠通過同時急切地加載Additives來解決這個加載Products,而不是依靠延遲加載。

var products = context.Products.Include(p => p.Additives); 

它將取出Additives爲加載Products相同查詢的一部分。它也會更有效率,因爲它只會加載連接到您返回的ProductsAdditives。儘管目前您正在加載所有Products,所以對於此確切查詢可能不會有很大改進。

+0

哦!好。好的建議。我將切換加載方法。 Surly,渴望加載更適合這個目的。謝謝! – elmodai

相關問題