MySQL + Code First + Lazy Load问题!

时间:2011-05-10 14:10:50

标签: mysql lazy-loading ef-code-first

在一个非常简单的房地产程序中我试图使用附加到现有数据库的EF Code First列出房屋的所有图像,我使用的是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:   执行时发生错误   命令定义。 看到内心   细节例外。
  ---&GT; MySql.Data.MySqlClient.MySqlException:   已经有一个开放的DataReader   与此Connection相关联   必须先关闭。
在   MySql.Data.MySqlClient.MySqlCommand.CheckState()
  在   MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(的CommandBehavior   行为)   MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(的CommandBehavior   行为)   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 个答案:

答案 0 :(得分:2)

  

...因此,当懒惰加载图像时,DataReader可能仍处于打开状态,这就是问题发生的原因。

这正是发生的事情,但我认为并不是你想的原因。 DataReader仍处于打开状态,不是因为Linq中的延迟执行,而是因为当您尝试访问尚未加载的其他属性时,您仍在迭代查询结果。当您调用.ToList()时,结果会立即返回并存储在客户端的List<TEntity>内存中,而不是一次返回1条记录。

您可以使用连接字符串中的MultipleActiveResultSets=true设置在MS SQL Server中解决此问题,但MySQL不支持此设置。但是,您应该能够做的是使用.Include("tablename")

急切加载您需要的其他数据
var houses = (from h in db.Houses.Include("Images")
              select h).Take(10);