2014-01-10 67 views
0

好吧...實體框架6問題的所有y'alls。實體框架上下文問題

我在寫一個使用EF的小型Intranet門戶。這是一個非常簡單的使用gridview的CRUD。 Everthings要游泳,但我在嘗試保存更改時遇到問題。

爲了在gridview上進行分頁,排序和過濾,我創建了一個包含實體對象列表的會話變量,然後將該會話變量綁定到gridview。

//Class level variables 
private nsdc_supplyEntities _context = new nsdc_supplyEntities(); 
private VlanClass _vc; 
private EnvironmentTypesClass _ec; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    _vc = new VlanClass(_context); 
    _ec = new EnvironmentTypesClass(_context); 

    if (!IsPostBack) 
    { 
     Session["vlans"] = _vc.GetAllVlans(); 
     BindData(); 
    } 
} 

protected void BindData() 
{ 
    GridView1.DataSource = Session["vlans"]; 
    GridView1.DataBind(); 
} 

protected void GridView1_EditVlan(object sender, GridViewEditEventArgs e) 
{ 
    GridView1.EditIndex = e.NewEditIndex; 
    BindData(); 
} 

這樣,如果用戶過濾列表中上下設置更小的結果或排序和網頁,然後做觸發回發一些其他的事件,GridView的設置保持不變。

但從我所知道的,會話[「vlans」]中的Vlans列表不再有上下文(由於回發事件?)。所以當我嘗試編輯選定的vlan並保存它(特別是當我嘗試將一個environment_type子實體添加到vlan實體時),我收到一個錯誤。

我已經嘗試將vlan條目重新連接到_context中,但是它帶來了一個「蠟燭球」。做這個的最好方式是什麼?

這裏是我的更新,因爲它代表:

protected void UpdateVlan(object sender, GridViewUpdateEventArgs e) 
{ 
    CheckBoxList environmenttypesCBL = (GridView1.Rows[e.RowIndex].FindControl("EnvironmenttypesCBL") as CheckBoxList); 
    int vlanid = Convert.ToInt32(((Label)GridView1.Rows[e.RowIndex].FindControl("lblid")).Text); 

    //At first I was creating a new instance of vlan in question and saving that, 
    //but then database and the Session["vlan"] variable (and gridview) is out of sync 
    //vlan editedVlan = new vlan(); 
    //editedVlan = _vc.GetVlanByID(vlanid); 

    //Get the vlan I am editing from Session["vlan"] 
    List<vlan> list = Session["vlans"] as List<vlan>; 
    vlan editedVlan = list.Find(i => i.id == vlanid); 

    //Tried reattaching but "The object cannot be detached because it is not attached to the ObjectStateManager." 
    //_context.Attach(editedVlan); 

    #region EnvironmentTypes 
    editedVlan.environment_type.Clear(); 
    if (environmenttypesCBL.Items.Count > 0) 
    { 
     foreach (ListItem l in environmenttypesCBL.Items.Cast<ListItem>()) 
     { 
      //tried adding an environment_type to the editedVlan but "The object cannot be detached because it is not attached to the ObjectStateManager." 
      if (l.Selected) 
       editedVlan.environment_type.Add(_ec.GetEnvironmentTypeByID(Convert.ToInt32(l.Value))); 
     } 
    } 
    #endregion 

    _vc.UpdateSelectedVlan(); 

    GridView1.EditIndex = -1; 
    BindData(); 
} 

回答

1

你_context創建您發表或讓每一個時間,和VLAN的列表被綁定到不同的環境作爲一個結果。

會話不關心POST或GET,我想你應該改變這樣的:

_vc = new VlanClass(_context); 
_ec = new EnvironmentTypesClass(_context); 

if (!IsPostBack) 
{ 
    Session["vlans"] = _vc.GetAllVlans(); 
    BindData(); 
} 

要這樣:

if (Session["vlans"] == null) 
{ 
    _context = new nsdc_supplyEntities(); // only create the context here not in the instance var declaration. 
    _vc = new VlanClass(_context); 
    _ec = new EnvironmentTypesClass(_context); 
    Session["vc"] = _vc; 
    Session["vlans"] = _vc.GetAllVlans(); 
    Session["context"] = _context; 
} 
else 
{ 
    _context = (DbContext)Session["context"]; // cast to your Context 
    _vc = (VlanClass) Session["vc"] ; 
} 

if (!IsPostBack) 
{ 
    BindData(); 
} 
+0

這是有趣的。這更優雅,我正在做什麼。我對其他的第二行有點困惑。會話變量是vlans的列表。我的猜測是你試圖將它附加到_vc或其他東西,但_vc只是一個包含一堆查詢方法的類的實例。我想會列出 list =(List <"vlans">)Session [「vlans」];會更有意義,但我不確定這就是你所得到的。 – Jeremy

+0

啊,是的......我搞砸了(將編輯)。但基本上你正在失去你的背景,因爲你正在創造一個新的。 –

+0

做了這項工作?希望得到upvote並回答檢查寶寶! –