MySQL + Code First + Lazy Load проблема! - PullRequest
4 голосов
/ 10 мая 2011

в очень простой программе для недвижимости. Я пытаюсь перечислить все изображения для дома, используя EF Code. Сначала прикрепленный к существующей БД, которую я имею, я использую MySQL Conector 6.3.6, вот мой код.

namespace CodeFirstMySQL
{
    class Program
    {
        static void Main(string[] args)
        {
            RealEstate db = new RealEstate();

            var houses = (from h in db.Houses
                         select h).Take(10);

            foreach (var house in houses)
            {
                Console.WriteLine(string.Format("Images for {0}", house.Address));
                foreach (Image image in house.Images)
                {
                    Console.WriteLine(string.Format("=> {0}", image.FileName));
                }
            }
        }
    }

    public class RealEstate : DbContext
    {
        public DbSet<House> Houses { get; set; }
        public DbSet<Image> Images { get; set; }
    }

    [Table("CADIMO")]
    public class House
    {
        [Column("CODIGO")]
        public int HouseId { get; set; }

        [Column("ENDERECO")]
        public string Address { get; set; }

        public virtual ICollection<Image> Images { get; set; }
    }

    [Table("CDIMIM")]
    public class Image
    {
        [Key]
        [Column("CODIGO", Order = 0)]
        public int HouseId { get; set; }

        [Key]
        [Column("CODIGO_I", Order = 1)]
        public int ImageOrder { get; set; }

        [Column("FILE_PATH")]
        public string FileName { get; set; }
    }
}

Когда я пытаюсь запустить это, я получаю следующую ошибку:

Изображения для Porto das Dunas
Исключение необработанного: System.Data.EntityCommandExecutionException: Ошибка при выполненииопределение команды. Подробности см. Во внутреннем исключении.
---> MySql.Data.MySqlClient.MySqlException: Уже существует открытый DataReader, связанный с этим подключением, который должен быть закрыт первым.
в MySql.Data.MySqlClient.MySqlCommand.CheckState ()
в MySql.Data.MySqlClient.MySqlCommand.ExecuteReader (поведение CommandBehavior)
в поведении MySql.DataM.Reader.Ed.System.Data.Common.DbCommand.ExecuteReader (поведение CommandBehavior) в System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands (EntityCommand entityCommand, поведение CommandBehavior)
--- Отслеживание конца стека внутренних исключений ---

Интересно то, что если я использую следующий запрос

List<House> houses = (from h in db.Houses select h).Take(10).ToList();

, тогда он работает, но выполняется энергичная загрузка, потому что, когда я проверяю свойство Images дляв каждом доме они уже заселены.Итак, мой вопрос: можно ли использовать Lazy Load с MySQL и Code First?

Я знаю, что Linq не выполняет запрос, пока мы его не используем, поэтому, возможно, DataReader все еще открыт, когда приходит время ленитьсяЗагрузите изображения, и именно поэтому проблема возникает.

Любой свет по этому вопросу приветствуется.

спасибо, Андерсон Форталеза

1 Ответ

2 голосов
/ 10 мая 2011

... так что, возможно, DataReader все еще открыт, когда пришло время ленивой загрузки изображений, и именно поэтому проблема имеет место.

Именно так и происходит, ноЯ думаю, что не совсем та причина, по которой вы думаете.DataReader по-прежнему открыт не из-за отложенного выполнения в Linq, а потому, что вы все еще просматриваете результаты запроса, когда пытаетесь получить доступ к другому свойству, которое еще не загружено.Когда вы вызываете .ToList(), результаты сразу возвращаются и сохраняются в List<TEntity> в памяти клиента, а не возвращаются по 1 записи за раз.

Вы можете обойти это в MS SQLСервер использует параметр MultipleActiveResultSets=true в строке подключения, но MySQL не поддерживает этот параметр.Тем не менее, вы должны быть в состоянии загружать дополнительные данные, которые вам нужны, используя .Include("tablename")

var houses = (from h in db.Houses.Include("Images")
              select h).Take(10);
...