【问题标题】:How to have one single RESTier 0.6.0 service picking the database depending on the request?如何让一个 RESTier 0.6.0 服务根据请求选择数据库?
【发布时间】:2017-02-06 20:45:49
【问题描述】:

场景 A: 假设您在同一个 SQL Server/SQL Azure 实例上有多个数据库共享完全相同的结构,其中数据库名称是基于约定的,例如 db001、db002...单个 RESTier 服务必须能够为每个 REST 调用寻址正确的数据库,具体取决于要在请求标头或 URI 路径或查询字符串上提供的某些特征。

场景 B:单个 RESTier 服务必须能够处理多个连接字符串,在 web.config 文件中定义,具体取决于请求中提供的某些特征。

在这两种情况下,基本问题是相同的,单个 RESTier 服务能够处理对多个数据库的请求,其中客户端必须在每个请求上向要使用的数据库提交提示,这是典型的多租户场景.我使用的是 RESTier 0.6 版,实体集自动从实体框架模型中公开:

public class Entities : EntityFrameworkApi<SalesEntities> { 

问题是,您建议如何实施这种多租户场景?

【问题讨论】:

    标签: odata restier


    【解决方案1】:

    您可以使用如下所示的参数化 routePrefix 并解析 URL 的那部分 (HttpContext.Current.Request.RawUrl)。

    config.MapRestierRoute<Entities>("EntitiesApi", "api/{entitiesConfig}", new RestierBatchHandler(server)); 
    

    从您的 Web.config 中检索正确的 connectionString 并使用它来创建 DbContext:

    Match match = Regex.Match(HttpContext.Current.Request.RawUrl, @"/api/(?<entitiesConfig>[A-Za-z0-9\-]+)/", RegexOptions.IgnoreCase);
    string entitiesConfig = "DefaultEntitiesContext";
    if (match.Success)
        entitiesConfig = match.Groups["entitiesConfig"];
    string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[entitiesConfig].ConnectionString;
    var db = new SalesEntities(connectionString);
    

    【讨论】:

    • 感谢您的回复,您是否在RESTier 中自己尝试过,如果是,在哪个版本中?我不再与 RESTier 合作,但最终出现在此页面的其他人可能会从您的建议中受益。
    • 是的,我自己在 RESTier 0.6.0 中使用它。我已更改代码以匹配您的示例。
    【解决方案2】:

    对于您的场景,我认为您将有两个 DbContext,每个都连接到一个数据库实例,那么这样的事情对您有用吗?

    在configure方法中,我们调用了两次MapRestierRoute,每次都会处理一个不同路由前缀的DbContext,当用户发起请求时,请求的URL会包含前缀并自动路由到相关的数据库实例。

    config.MapRestierRoute>( "TrippinApi", "api/TrippinA", new RestierBatchHandler(server)); config.MapRestierRoute>("TrippinApi", "api/TrippinB", new RestierBatchHandler(server));

    如果您对此有任何问题,请告诉我。

    【讨论】:

    • 不得不承认我还没有找到如何使用路由前缀(“TrippinA”,“TrippinB”)来选择对应的数据库实例(比如说,“DBTrippinA”,“ DBTrippinB"),以便以下两个请求针对同一 RESTier 控制器上的不同数据库:myServer/api/TrippinA/ProductsmyServer/api/TrippinB/Products
    • 对于每个 DBInstance,您应该首先使用代码并创建两个扩展 DBContext 的类,每个 DbContext 与一个 DbInstance 相关。在路由映射期间,每条路由都与一个 DbContext 相关。这样,我们就可以制作与 DbContext 相关的路由。但请注意,这不是自动配置的,而是在应用程序启动期间配置的。
    • 这意味着我必须提前确定我愿意支持的最大租户数量(10 个租户意味着 10 个 DbContexts 意味着 10 个硬编码的路由),这作为多租户方法不会对我来说很有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    相关资源
    最近更新 更多