こんにちは、仲間のスタッカー(またはオーバーフロー、どちらか好きな方)、これは他の何よりも清潔さと便利さの問題ですが、私だけがそれについて疑問に思ったことは想像できないので、ここに行きます...
EntityFrameworkデータコンテキストを使用する基本的な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]
方法は、最終的にデータコンテキストへの直接パススルーになります。
要約すると、私が基本的に目指しているのは、DbSetプロパティの場合と同じように、WCFが公開するデータコンテキストクラスのメソッドをマークすることです。テイカーはいますか?
ありがとう!J