2012-12-19 8 views
0

大家下午好,同事們(或者說是溢出者,無論你喜歡什麼),這比其他任何事情都更加清潔和方便,但我無法想象我是唯一一個曾經想過的人,所以我們走了。 ..使用WCF數據服務在DbContext上直接引用一個方法?

我有一個使用我的實體框架數據上下文的基本OData啓用WCF數據服務類。

[JsonpSupportBehavior] 
public class ControlBindingService : DataService<MyDataContext> 
{ 
    public static void InitializeService(DataServiceConfiguration config) 
    { 
     config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; 
     config.DataServiceBehavior.AcceptCountRequests = true; 
     config.SetEntitySetAccessRule("*", EntitySetRights.All); 
     config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);   
    } 

    protected override MyDataContext CreateDataSource() 
    { 
     if (HttpContext.Current == null) 
      throw new InvalidOperationException("The WCF Data Services implementation must be hosted in IIS."); 

     string username; 
     if (HttpContext.Current.User.Identity.IsAuthenticated) 
      username = HttpContext.Current.User.Identity.Name; 
     else 
     { 
      // The request didn't have user identity, attempt to find UserName in the 
      // request header before returning 401 to the caller. 
      if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["UserName"])) 
      { 
       username = HttpContext.Current.Request.Headers["UserName"]; 
       // REVIEW: We should validate user before passing it to the datacontext. 
      } 
      else 
       throw new DataServiceException(401, "Client did not pass required authentication information."); 
     } 

     return MyDataContext.GetInstance(username); 
    } 

    [WebGet] 
    public List<DailyKeyPerformanceIndicator> GetResourceKPIs(
     int resourceId, string jsonStart, string jsonEnd, int scenarioId) 
    { 
     DateTime start = jsonStart.DeserializeJson<DateTime>(); 
     DateTime end = jsonEnd.DeserializeJson<DateTime>(); 

     if (scenarioId < 1) 
     { 
      scenarioId = CurrentDataSource.GetScenarios() 
       .Single(s => s.IsProduction).ScenarioID; 
     } 

     return CurrentDataSource.GetDailyResourceKPI(
      scenarioId, start, end, resourceId); 
    } 
} 

數據上下文是一個標準(代碼優先)DbContext實現與性能露出實體集等。

然而,我們也有方法,有揭露,我們希望一些表強制執行一些約束。特別是(見下面的代碼),我們想知道調用者想要使用哪些數據,以便我們只返回適當的結果。例如,如果調用者想要從employees表中獲取行 - 他們可能想要獲取所有行,或者只獲取具有更新權限的行。

[Serializable] 
public partial class MyDataContext : DbContext 
{ 
    static MyDataContext() 
    { 
     Database.SetInitializer<MyDataContext>(null); 
    } 

    public MyDataContext() 
     : base("name=MyDBString") 
    { } 

    // Standard table properties... 

    public DbSet<User> Users 
    { 
     get { return this.Set<User>(); } 
    } 

    public DbSet<UserSetting> UserSettings 
    { 
     get { return this.Set<UserSetting>(); } 
    } 

    public DbSet<SettingDefinition> SettingDefinitions 
    { 
     get { return this.Set<SettingDefinition>(); } 
    }  

// Restricted table methods... 

public DbSet<Client> GetClients(
    DatabasePermissions perms = DatabasePermissions.Select) 
{ 
    // getPermissibleSet is a method in a helper class that does some 
    // magical querying and produces a filtered DbSet. 
    return getPermissibleSet<Client>(perms); 
} 

public DbSet<Employee> GetEmployees(
    DatabasePermissions perms = DatabasePermissions.Select) 
{ 
    // getPermissibleSet is a method in a helper class that does some 
    // magical querying and produces a filtered DbSet. 
    return getPermissibleSet<Employee>(perms); 
}  
} 

現在到了問題的根源......我想什麼,以避免做的是寫每一個[WebGet]我的數據上下文「限制表法」。原因實際上只不過是冗餘 - [WebGet]方法最終會成爲數據上下文的直接傳遞。

所以總而言之,我會說我基本上想要做的是從我的數據上下文類中標記WCF將以與它的DbSet屬性相同的方式公開的方法。任何接受者?

謝謝! J

回答

0

這是一個有趣的問題。我正在嘗試做類似的事情。這是投擲飛鏢在這裏,但你有沒有嘗試過這樣的事情?你應該將泛型分開,所以你不需要爲每種類型創建一個獨特的上下文,但是你似乎應該能夠用泛型刪除重複的代碼。

[Serializable] 
public partial class MyDataContext<T> : DbContext where T : class 
{ 
    static MyDataContext() 
    { 
     Database.SetInitializer<MyDataContext>(null); 
    } 

    public MyDataContext() 
     : base("name=MyDBString") 
    { } 

    // Standard table properties... 

    public DbSet<T> SettingDefinitions 
    { 
     get { return this.Set<T>(); } 
    } 

    // Restricted table methods... 

    public DbSet<T> GetClients(
     DatabasePermissions perms = DatabasePermissions.Select) 
    { 
     // getPermissibleSet is a method in a helper class that does some 
     // magical querying and produces a filtered DbSet. 
     return getPermissibleSet<T>(perms); 
    } 
}