在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be closed first”。
public class User { public long UserId { get; set; } public string UserName { get; set; } public string UserPwd { get; set; } public DateTime UserCreateDate { get; set; } public DateTime LastLoginDate { get; set; } public DateTime LastActivityDate { get; set; } public int UserRoleId { get; set; } public virtual UserProfile UserProfile { get; set; } }
public class UserProfile { [Key, ForeignKey("User")] public long UserId { get; set; } public int Gender { get; set; } public string NickName { get; set; } public string Signature { get; set; } public string Intro { get; set; } public DateTime? Birth { get; set; } public string Location { get; set; } public string Website { get; set; } public string Qq { get; set; } public string WeiBo { get; set; } public string Medals { get; set; } public string Phone { get; set; } public string Email { get; set; } public bool IsSendEmail { get; set; } public virtual User User { get; set; } }
如果有User的对象,想访问自己的UserProfile里的属性值,直接访问会出现异常。
例如
@p.UserName //ok
@p.UserProfile.Intro //出现异常
异常为There is already an open DataReader associated with this Command which must be closed first。
导航属性UserProfile采用的是延迟加载(惰性加载),在访问它的时候才加载。在读对象自己的属性值时已经打开了一个DataReader,然后在访问到延迟加载的导航属性时,又需要DataRead来读取这个导航属性中的各个属性值,而前一个DataReader还没有关闭。
解决的办法是采用多数据结果集。
多数据结果集(Multiple Active Result Sets,简称MARS)-它允许在单个连接上执行多重的数据库查询或存储过程。这样的结果是,你能够在单个连接上得到和管理多个、仅向前引用的、只读的结果集。可以在一个Command对象上同时打开多个DataReader,节约数据库联接所耗费的服务器资源。
在数据库的连接字符串上添加MultipleActiveResultSets=true
<add name="CRGDatabase" connectionString="Data Source=./;Initial Catalog=DB;uid=User;pwd=Pwd;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient"/>