2016-09-08 20 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

相关问题