Я борюсь с указанной выше ошибкой. Я нашел здесь разные ответы (переполнение стека), но ни один из них не решает мою проблему, связанную с ошибкой.

Я просто включаю MARS в своей ConnectionString, но безуспешно.

У меня классный продукт

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; }
}

}

И класс Additive, представляющий добавки в продуктах

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>
3
elmodai 8 Сен 2016 в 17:08

3 ответа

Лучший ответ
context.Products.Where(x=>x.Additives.Any(y=>y.Key==key)).ToList();

Ваш код не работает, потому что вы лениво загружаете добавки во время итерации по продуктам ...

Но сама итерация - ерунда ... если вы хотите что-то искать в базе данных, позвольте базе данных делать свою работу, давая ей что-то для поиска, вместо того, чтобы говорить ей дать вам все, а затем сортировать то, что вы хотите. ..

Представьте, если бы в вашем столе было несколько сотен миллионов товаров ...

Вы бы загрузили ВСЕ продукты и пролистали их целую вечность ...

Посмотрите LINQ

Посмотрите на .Where ()

Посмотрите .Select ()

Познакомиться с лямбда-выражениями

4
DarkSquirrel42 8 Сен 2016 в 14:38

Чтобы быть точным, при итерации через IQueryable используется открытое средство чтения данных (так что вы можете прекратить итерацию, не читая все продукты из базы данных). Если вы выполняете отложенную загрузку добавок, 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();
}
1
bubi 8 Сен 2016 в 16:11

Вы должны иметь возможность исправить это, нетерпеливо загружая Additives одновременно с Products, вместо того, чтобы полагаться на отложенную загрузку.

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

Это приведет к получению Additives как части того же запроса, который загружает Products. Это также будет более эффективным, поскольку будет загружать только Additives, которые связаны с Products, который вы возвращаете. Хотя вы загружаете ВСЕ Products в данный момент, это не может быть большим улучшением для этого точного запроса.

1
Bradley Uffner 8 Сен 2016 в 16:20