2013-01-06 208 views
2

我正在使用EF 5,並且啓用了延遲加載。當我從數據庫中檢索一個實體時,它完美地工作。實體框架檢索導航屬性

這裏是我的問題。我有一個通用的存儲庫來執行數據庫操作。

public int Update(T t) //Update method implemented at repository layer 
    { 
     dbSet.Attach(t); 
     context.Entry(t).State = EntityState.Modified; 
     return context.SaveChanges(); 
    } 

    public T Update(T t, int id) //This Method calls the above method to 
    { 
     if (Update(t) > 0) 
     { 
      //Now entity is updated so retrieve the entity from the database. 
      return Get(id); //This line of code doesn't return entity with reference. It does return the updated entity. 
     } 
     return null; 
    } 

現在,當我查詢實體使用主鍵來獲得更新的實體,它給了我更新的實體,但是沒有任何參考性。我不能在這裏使用懶加載,因爲它會引發異常。

更新enttity後,我注意到dbSet.Local有更新的實體。所以我試圖清除之前我檢索更新的實體,但沒有運氣。我也嘗試通過上下文重新加載實體,但不重新加載導航屬性。我無法使用引用屬性作爲我使用的通用存儲庫。 我可以完成的唯一方法是處理並創建上下文和dbset的新實例。

我想返回填充了關係屬性的更新實體。有沒有人有一個好的解決方案。

+0

有什麼異常? – 2013-01-06 23:34:14

+0

它不會拋出異常。所有關聯的屬性都是空的。 –

+0

你說,因爲它拋出一個異常,你不能使用延遲加載。 – 2013-01-14 02:42:50

回答

1

我懶加載啓用

我附上POCO實體

我從您的意見假設某處在您的應用程序正在實例化你的實體,就像這樣new MyEntity(),因爲它不是代理POCO,所以懶惰加載將不起作用。

考慮到你說你啓用了延遲加載,最簡單的方法就是使用代理POCO來完成你想要做的事情。下面是使用下面實例化一個實體的任何地方:

MyEntity entity = MyContext.MyEntities.Create(); 

延遲加載應該適用於您。如果您不想這樣做,或者這不起作用,那麼最好的選擇是從數據庫中提取現有實體(作爲動態代理)並從您的POCO中填充。因此,在你的資料庫更新方法:

編輯

我要指出的是,還可以做到這一點沒有一個往返到數據庫。看評論。

public T Update(T poco) 
{ 
    //get the entity from db 
    T proxyPoco = context.Set<T>().Find(id); 

    //alternatively just create the proxy, set the id and attach. 
    //no db retrieval. 
    //T proxyPoco = context.Set<T>.Create(); 
    //proxyPoco.Id = poco.Id; 
    //context.Set<T>.Attach(proxyPoco); 

    if(proxyPoco == null) 
    { 
    //throw an exception or handle case where the entity is not found. 
    //unecessary if using alternative above. 
    } 
    else 
    { 
    //set the proxy poco values using your original poco 
    context.Entry<T>(proxyPoco).CurrentValues.SetValues(poco); 
    } 
    context.SaveChanges(); 
    return proxyPoco; 
} 

因爲您返回代理POCO延遲加載應該工作。 其他不太理想的選項是:

  1. 放棄上下文並再次獲取實體。
  2. 使用反射顯式加載該實體的引用和集合。
+0

如何填寫更新後的值?我使用的是泛型類,所以我無法訪問屬性。目前我使用第二種方法。我重新創建新的上下文。我想有一個更好的解決方案。 –

+0

@JigarPatel我越看越你的問題,我就越變得困惑。爲什麼你甚至需要檢索實體?據推測,你已經有了一個實體的參考,因爲你將它傳遞給你的更新方法。也許你需要在你的問題中包含進一步的細節。 – 2013-01-16 10:13:54

+0

@JigarPatel'我如何填寫更新後的值?'。您必須在運行更新方法之前的某個階段在實體上設置值,否則您沒有理由附加和保存更改。 – 2013-01-16 10:30:04

1

SaveChanges返回int。您希望實體回來,試試這個:

public T Update(T t) 
{ 
    dbSet.Attach(t); 
    context.Entry(t).State = EntityState.Modified; 
    context.SaveChanges(); 
    return t; 
} 
+0

這不會返回參考/導航屬性。在更新期間,引用屬性爲空,所以它不會被更新。但是,即使我嘗試從數據庫中再次檢索它,它也不會返回導航屬性。我仍然可以檢索除我更新的實體之外的任何其他實體。 –