2011-12-11 81 views
2

我需要將EF中的Context對象傳遞給WCF方法。將實體框架上下文對象傳遞給WCF

通常情況下,我在WCF方法中創建Context對象,並在方法調用結束之前處理它,對於我的大多數方法來說工作正常。

但是,我需要將Context對象(特別是DBContext)從MVC控制器傳遞到我特定的WCF方法,因爲我爲某些查找表啓用了緩存。我需要傳遞給這個特定的Context對象(我在Global.asax文件的Application_Start方法中設置的那個對象),而不是我在上面的語句中做的,因爲我將這個特定的對象用於SqlDependency。如果我嘗試創建新的DBContext對象,我不能使用SqlDependency,因爲我會得到一個錯誤,告訴我需要在數據庫調用之前啓用SqlDependency。

問題是,當我嘗試啓動我的WCF測試客戶端工具時,出現以下錯誤(縮短了簡潔性),我知道該工具與正確聲明KnownType屬性(即DBContext對象) 。請注意,WCF項目編譯得很好。我需要一些關於這個特定部分的幫助,因爲我從未在我的WCF服務中使用KnownType。它們都是簡單的類型(int,string等)。

Error: Cannot obtain Metadata from http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex

If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange

Error URI: http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex Metadata contains a reference that cannot be resolved:

,我有以下OperationContract的代碼在我的WCF服務:

[OperationContract] 
     IEnumerable<Category> GetCategories(YeagerTechEntities DbContext); 

我有我的WCF服務的以下DataContract代碼:

namespace YeagerTechModel 
{ 
    [Serializable] 
    [DataContract(IsReference = true)] 
    [KnownType(typeof(YeagerTechEntities))] 
    public partial class Category 
    { 
     public Category() 
     { 
      this.Projects = new HashSet<Project>(); 
     } 

     [DataMember] 
     public short CategoryID { get; set; } 
     [DataMember] 
     public string Description { get; set; } 

     [DataMember] 
     public virtual ICollection<Project> Projects { get; set; } 
    } 

} 

最後,下面是我的WCF方法:

public IEnumerable<YeagerTechModel.Category> GetCategories(YeagerTechEntities DbContext) 
     { 
      //YeagerTechEntities DbContext = new YeagerTechEntities(); 

      DbContext.Configuration.ProxyCreationEnabled = false; 

      IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0).AsCached("Categories").ToList(); 
      //IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0); 

      CloseConnection(DbContext); 

      return category; 
     } 
+0

如果你改變你的代碼返回null,這個錯誤會消失嗎?如果你也擺脫了'KnownType'呢?試圖像這樣拆分代碼,一次刪除一個潛在的故障點,將有助於隔離問題。 –

+0

我在發佈錯誤後將KnowType屬性放入DataContract中。 – sagesky36

+0

我不認爲你應該在界面中傳遞上下文。我不認爲它會被序列化,並且可能會導致巨大的麻煩。你有沒有嘗試刪除它(可能會讓你的身體變空)?您可以使用其他方法傳遞它,但應該在服務器端進行選擇。 –

回答

1

您需要註冊表/服務定位器模式之後的單例對象。該對象將持有對全局對象的引用。例如,在應用程序啓動時,您將使用您的上下文使用SqlDependency填充此對象,您將使用註冊表訪問控制器操作和服務操作中的此上下文。

無論如何,非常仔細的工作。 SqlDependency和EF在一起玩並不好,因爲它會讓你的背景變得長久。長期居住背景是in most cases anti-pattern。永遠不要將該上下文用於其他任何內容,然後加載緩存的數據。不要將其用於數據修改或加載非緩存關係!在第一個查詢中將實體加載爲未跟蹤(在查詢中爲AsNoTracking擴展方法),並關閉該上下文的代理創建和延遲加載。

另外請注意,EF中的查詢總是在數據庫中執行。我不知道你什麼AsCached應該做的,但我有點懷疑它會工作。你需要的可能是:

var category = DbContext.Categories.Local 
         .Where(p => p.CategoryID > 0) 
         .ToList(); 

我不會使用SqlDependency EF。我會直接使用ADO.NET和SQL。爲了在EF中進行緩存,我會檢查EF Caching provider以使用大多數情況下足夠的二級緩存。

+0

拉迪斯拉夫,感謝您的意見。在閱讀EF緩存提供者之後,似乎這對於我想要做的事來說太複雜了。另外,對於一些有用的和其他的,它不是。我只是等到EF將在後面的版本中創建一個緩存屬性。這對我來說很奇怪,爲什麼MS從4.0或4.1框架出來以後就沒有想到會有這樣的事情發生。希望他們能夠在即將到來的框架中儘快實施。我知道NHibernate內置了一些SQL依賴緩存。 – sagesky36

相關問題