在實體對象中訪問導航屬性里的屬性值出現異常“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"/>
