0

下午好,堆垛机(或溢出机,无论您喜欢哪个),这比其他任何事情都更像是一个清洁和便利问题,但我无法想象我是唯一一个对此感到疑惑的人,所以我们开始......

我有一个基本的启用 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 属性相同的方式公开这些方法。有接盘侠吗?

谢谢!Ĵ

4

1 回答 1

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);
    }
}
于 2013-07-23T12:46:44.163 回答