2011-03-19 60 views
40

我有這樣的觀點:的ObjectContext的實例已被設置,並且不再能夠用於需要連接的操作

@model MatchGaming.Models.ProfileQuery 
@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2>  
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm("Results", "Profiles")) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>ProfileQuery</legend> 
     @Html.EditorFor(model=>model.SearchString) 
     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

我有這樣的控制器爲HttpPost:

[HttpPost] 
public ActionResult Results(ProfileQuery profileQuery) 
{ 
    Debug.Write(profileQuery.SearchString); 
    using(var db = new MatchGamingEntities()) 
    { 
     var SearchUserName = db.Users.SingleOrDefault(a=> a.UserName.Contains(profileQuery.SearchString)); 
     var Users = from m in db.Users 
        join m2 in db.MyProfiles on m.UserId equals m2.UserId 
        where m.UserName == SearchUserName.UserName 
        select new UserViewModel 
        { 
         UserName = m.UserName, 
         LastActivityDate = m.LastActivityDate, 
         Address = m2.Address, 
         City = m2.City, 
         State = m2.State, 
         Zip = m2.Zip 
        }; 

     return View(Users.AsEnumerable()); 
    } 
} 

這裏是該信息查看結果:

@model IEnumerable<MatchGaming.Models.UserViewModel>  
@{ 
    ViewBag.Title = "Results"; 
} 

<h2>Results</h2> 

<fieldset> 
    <legend>UserViewModel</legend> 
    @foreach (var item in Model){ 
    <div class="display-label">UserName</div> 
    <div class="display-field">@item.UserName</div> 

    <div class="display-label">LastActivityDate</div> 
    <div class="display-field">@String.Format("{0:g}", item.LastActivityDate)</div> 

    <div class="display-label">Address</div> 
    <div class="display-field">@item.Address</div> 

    <div class="display-label">City</div> 
    <div class="display-field">@item.City</div> 

    <div class="display-label">State</div> 
    <div class="display-field">@item.State</div> 

    <div class="display-label">Zip</div> 
    <div class="display-field">@item.Zip</div> 
    } 
</fieldset> 

我不斷收到此錯誤:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

我想不通爲什麼。

回答

51

我猜測,問題在於LINQ查詢的執行被推遲到開始在您的視圖中訪問它們。此時已經處置db

試試這個:

return View(Users.ToList()); 

添加ToList()

這將迫使從DB處置db前取。

+1

我試過了,然後constructor設置

this.ContextOptions.LazyLoadingEnabled = false; 

得到這個錯誤:「對象引用不設置到對象的實例」這個錯誤發生在您張貼我要更改的行上。這就是拋出異常 – anthonypliu 2011-03-19 06:12:54

+0

@anthonypliu,我從我的例子中刪除不需要的'AsEnumerable()'作爲ToList()已經是Enumerable。查看視圖代碼可能是因爲String.Format(),LastActivityDate可能爲null並導致NullReferenceException。它應該工作。否則,進入代碼並找到空引用 - 最有可能是用戶對象或視圖中的某些東西。 – 2011-03-19 06:19:47

+1

我試過,但它沒有工作,我想我知道問題的一部分,我的第一個視圖沒有正確發佈ProfileQuery模型,因爲我試圖打印profileQuery.SearchString,並且我得到一個空的異常,所以SearchString甚至沒有通過到HttpPost – anthonypliu 2011-03-19 06:22:58

10

的問題是這一行:

return View(Users.AsEnumerable()); 

枚舉是懶洋洋地評估,因爲你的MatchGamingEntities通過枚舉您的視圖可以循環之前設置的,當它試圖做到這一點的代碼死亡。

您必須找到一種方法來管理對象的生命週期,使其超出控制器方法,或者將所有數據傳遞到內存中的Model對象,然後再將它們傳遞給視圖。

參見here有類似的解釋。

1

的問題是,你正在發行淺拷貝,當你做:

var Users = from m in db.Users 
       join m2 in db.MyProfiles on m.UserId equals m2.UserId 
       where m.UserName == SearchUserName.UserName 
       select new UserViewModel 
       { 
        UserName = m.UserName, 
        LastActivityDate = m.LastActivityDate, 
        Address = m2.Address, 
        City = m2.City, 
        State = m2.State, 
        Zip = m2.Zip 
       }; 

你需要做的是使一個UsersCopy,然後通過複製值到UsersCopy用戶迭代,然後返回UsersCopy在爲了做一個深度複製

喜歡的東西

List<User> UsersCopy = new List<User>(); 
foreach(user in Users){ 
    User u = new User(); 
    u.UserName = user.UserName; 
    u.Address = user.Address; 
    //... 
    UsersCopy.Add(u); 
} 
return View(UsersCopy); 
1

在你有孩子顯示屬性即行項目問題的情況下。這是爲我工作的髒修復。修復了我沒有檢索對象的子項目的問題:

header.MachineDataLines = header.MachineDataLines;

+2

骯髒的修復程序通常不是要走的路。從源頭上解決問題。 – Styxxy 2012-10-27 22:31:47

11

使用子句處置(讀:破壞)的MatchGamingEntities分貝上下文之前的查看有機會使用它。因此,儘管你可以列舉之前的項目(或)您通過用戶查看,更好的方法是放棄你使用使用條款,讓天然的垃圾收集完成其在你真正完成之後繼續工作 - 直到視圖完成後才能完成。

欲瞭解更多信息,請參閱this question on the Entity Framework and Connection Pooling

9

一個壞的習慣,但你可以的Context

+3

高度重視「壞」。如果你認爲你需要這樣做,你需要重新思考你的SOC戰略。 – Andrew 2013-05-30 15:21:31

+0

使它在爲上下文使用語句時不那麼糟糕的包裝,因此在命令被調用後該設置被銷燬 – kravits88 2013-12-11 03:37:35

相關問題