【问题标题】:MySQL + Code First + Lazy Load problem !MySQL + Code First + Lazy Load 问题!
【发布时间】:2011-05-10 14:10:49
【问题描述】:

在一个非常简单的房地产程序中,我尝试使用附加到现有数据库的 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: 执行时发生错误 命令定义。 看内心 详情例外。
---> MySql.Data.MySqlClient.MySqlException: 已经有一个打开的 DataReader 与此连接相关联 必须先关闭。
在 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 实体命令、命令行为 行为)
--- 内部结束 异常堆栈跟踪 ---

有趣的是,如果我使用以下查询

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

然后它可以工作,但是会执行一个急切的加载,因为当我检查每个房子的 Images 属性时,它们已经被填充了。所以,我的问题是,延迟加载可以与 MySQL 和 Code First 一起使用吗?

我知道 Linq 在我们使用它之前不会执行查询,所以当需要延迟加载图像时 DataReader 可能仍然打开,这就是问题发生的原因。

感谢您对此问题的任何了解。

谢谢你 安德森福塔莱萨

【问题讨论】:

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


    【解决方案1】:

    ...所以当需要延迟加载图像时,DataReader 可能仍处于打开状态,这就是问题发生的原因。

    这正是正在发生的事情,但我认为这并不完全是您认为的原因。 DataReader 仍然打开,不是因为 Linq 中的延迟执行,而是因为当您尝试访问尚未加载的其他属性时,您仍在遍历查询结果。当您调用 .ToList() 时,结果会一次全部返回并存储在客户端内存中的 List&lt;TEntity&gt; 中,而不是一次返回 1 条记录。

    您可以在 MS SQL Server 中使用连接字符串中的设置 MultipleActiveResultSets=true 解决此问题,但 MySQL 不支持此设置。不过,您应该能够使用.Include("tablename") 预先加载您需要的额外数据

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

    【讨论】:

    • 有趣的是,我什至不必这样做,即使我的图像集合是一个虚拟属性,如果我在查询结束时调用 ToList(),图像也会被急切加载。我认为 MySQL 没有办法解决这个问题,因为它不支持 MultipleActiveResultSets。
    猜你喜欢
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多