使用Entity Framework (v6.1.3)突然遇到這個問題了,之前一直好好的,怎麼破? 此處省略了多次在“好”與“壞"的項目中試驗的過程(苦啊),直接給出答案。答案是:沒有按DbContext的機制來進行DbSet的實例化導致的。(我遇到的情況) 我們一般在自己的DbContext里這樣
使用Entity Framework (v6.1.3)突然遇到這個問題了,之前一直好好的,怎麼破?
此處省略了多次在“好”與“壞"的項目中試驗的過程(苦啊),直接給出答案。答案是:沒有按DbContext的機制來進行DbSet的實例化導致的。(我遇到的情況)
我們一般在自己的DbContext里這樣寫
public DbSet<MyEntity1> MyEntity1Set { get; set; }
這樣就沒問題,不用為MyEntity1Set實例化,就能直接使用,基類幫做了實例化工作。
問題出在,如果我們在自己的DbContext的構造方法或其它地方自己做實例化,後面的代碼(比如運行到ToList()的時候)就很可能出現標題的異常。
DbContext並不是只能創建DbSet<>類型的屬性,而是提供了一個virtual的Set<>方法 DbSet<TEntity> Set<TEntity> 。允許我們override來修改這個實例化的過程,即是說,所有DbSet實例化,都應該在此方法中進行。前面說的”基類幫做了實例化工作“也是調用Set<>方法。
但是,也有人在在這個方法中通過反射把當前DbContext對象的對應的屬性值作為Set<>方法的返回值,這個是非常違背DbContext.Set<>的機制,非常不可取的。
原因搞清楚,解決起來就簡單了。如果只是用原本的DbSet就不用override這個Set<>方法,也不用自己實例化了。如果要使用自己的類型(就像我用MockDbSet)代替DbSet,只需要這樣寫:
public override DbSet<TEntity> Set<TEntity>() { return new MockDbSet<TEntity>(); }
當然了,MockDbSet是DbSet的子類。
這樣,這個異常就消失了,起碼在我這裡是這樣。如果你遇到了這個異常,原因不一樣,或者你照上面做了,還是解決不了,歡迎留言探討。