简体   繁体   中英

Two Azure Mobile Services (.NET backend) sharing the same Database

I have two Azure Mobile Services (.NET backend) which share the same Azure Database. Let say Service "X" and "Y". The database is created by service "X" (when it ran for the first time) and created tables "TA" with schema name "X". Then I ran service "Y" which created the same tables "TA" and "TB" in the same database but with schema name "Y".

Now I want to make service "Y" to use schema "X" to make sure both services use the same data. Inside the "TADataController" I changed the code to:

    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);
        // MyContext context = new MyContext(Services.Settings.Name.Replace('-', '_'));
        YContext context = new YContext("X");
        DomainManager = new EntityDomainManager<ADataController>(context, Request, Services);
    }

Also in the "YContext" class

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            //string schema = ServiceSettingsDictionary.GetSchemaName();
            //if (!string.IsNullOrEmpty(schema))
            //  modelBuilder.HasDefaultSchema(schema);
            modelBuilder.HasDefaultSchema("X");
    }

but when I try to access the data inside "TADataController" using Query(), I get a SqlException with message "The specified schema name "X" either does not exist or you do not have permission to use it." I doubt that permission would be the issue as both services use the same Azure Database account and also clearly the schema exists as my other service uses it! so I cannot figure out what the problem is.

I also tried:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var entityConfig = modelBuilder.Entity<UserProfileData>();
        entityConfig.ToTable("UserProfileDatas", "X");
    }

but the same exception was raised. There are some information on the web for transferring data to another schema which could be helpful if I wanted to transfer my data to service "Y". But I want to use both services "X" and "Y" on a shared database.

UPDATE: I realized that ServiceSettingsDictionary.GetSchemaName() used in the OnModelCreating returns the name of the schema based on the configuration, so I uploaded the original codes:

    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);
        MyContext context = new MyContext(Services.Settings.Name.Replace('-', '_'));
        DomainManager = new EntityDomainManager<ADataController>(context, Request, Services);
    }

and

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            string schema = ServiceSettingsDictionary.GetSchemaName();
            if (!string.IsNullOrEmpty(schema))
                modelBuilder.HasDefaultSchema(schema);
    }

then in the management portal, I added one item to Configuration\\App Settings with Key=MS_TableSchema and Value=X. Then debugged the code again, I realized that ServiceSettingsDictionary.GetSchemaName() returns "X" as I wanted, but again the controllers throw a SqlException with message "The specified schema name "X" either does not exist or you do not have permission to use it." when I use the Query() method.

Just so that I understand -- you want your two services to access the same set of tables in the same database? Not just using the same database but the same tables?

You can easily reuse the same database but we set each mobile service using it up with a separate schema and permissions to only access that schema so that two services won't inadvertently interfere.

However, it sounds like you want them to access the same tables, right? This means that in addition to changing the schema in your service you also need to set the permissions for the mobile user in the DB to access that schema.

You can get the user using the kudu site under the Environment tab (look for the MS_TableConnectionString connection string):

https://<your service>.scm.azure-mobile.net/Env

And you can set the permissions for that user using the grant command -- you can see an example her:

https://weblogs.asp.net/fredriknormen/database-migration-and-azure-mobile-service-adventure

Hope this helps!

Henrik

When a mobile service named 'MSName' is created, a schema with the name 'MSName' is defined in the database, and a user is created with permission to access that schema only. That is the user in the default connection string which the mobile service will use when connecting to the database in the runtime. So if you have a service 'X' and try from it to access the service 'Y', the user it's using will not have permissions to do so.

There are a few options you can do to solve that. One is to find the user for service 'Y' (using one of the SQL server management tools) and grant it access to the schema for 'X'. Another option is to, when creating the context in the mobile service Y not to use the default connection string ("Name=MS_TableConnectionString"), but a connection string which uses the user for 'X'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM