Is it possible to create read-only synonym in SQL Server? - c#

We have 2 different databases DB1 and DB2 with tables in DB2 referring to tables in DB1.
We are looking into the possibility of using SYNONYMS with read-only access in DB2 and use EntityFramework to refer to these SYNONYMS as tables in DB2.
Since currently EF doesn't span across multiple databases, after reading this article (http://rachel53461.wordpress.com/2011/05/22/tricking-ef-to-span-multiple-databases/) we are one step ahead, but, we want to only have read-only access to the newly created SYNONYMS.
Any help is greatly appreciated!

You can create a schema for your synonym (such as "EntityFramework" or "EF" for simplicity). Create a role for your schema, naming it something to the tune of "EntityFrameworkUser".
Now there are two paths, here- this first one if you only ever have SELECT access, or the second one if you may also need EXECUTE access.
FIRST:
Going into the properties of your EntityFramework schema, you can navigate to Permissions, search for and add your EntityFrameworkUser role, and check only SELECT in the list of permissions below.
SECOND:
Going into the properties of your EntityFrameworkUser role, you can navigate to Securables, go to "Search..." for securables, use 'All objects belonging to the schema' with your EntityFramework schema.
For each of the objects showing up as a result, which should just be Synonyms (unless you also made new tables/SPs in the "EntityFramework" schema), you can grant access to "Select", and leave everything else unchecked unless you want the user to have more or less power with those objects.
REGARDLESS:
This will allow you to have visibility to the table without write/execute access. Assign whichever server user needs this readonly access, and add them to the "EntityFrameworkUser" role. In my case, there's a "WebApplication" and a "DesktopApplication" user, both of which are assigned to the "EntityFrameworkUser" role.
This should solve your issue of visiblity, while restricting write and execute access within the system.

Related

SqlConnection.ChangeDatabase - How to provide Schema?

I'm a bit confused by SqlConnection's ChangeDatabase(string databaseName).
I thought database names didn't have to be unique if they aren't in the same schema, for example I can have dbo.DatabaseName and hr.DatabaseName .
Every example of ChangeDatabase that I have seen though only uses the database Name ... is that just laziness and I can actually provide the full name by using
"[dbo].DatabaseName" as a parameter? Or is there something more to it ?
In Microsoft SQL Server, databases are not associated with schemas the way you think.
If you want to see a parent-child relation between them, I would say the database is the parent.
In a database, multiple schemas can exist. Once you create them, you can then define tables and other database objects (even users) that are part of one of the schemas you defined at database-level.
So, the ChangeDatabase method does nothing but executing a "USE {DBNAME}" statement in T-SQL.
Take a look: USE (Transact-SQL)

dynamically add column to model and show relevant field to add, edit and delete the field data in view asp.net mvc enityframework?

I Want to let user decide which column or field he want's to add in Objectand depending on what data type he has chosen to create that field, user should able to make CRUD operation on that object with data type chosen by him to create that custom field. Is it possible or not, If yes what are the optimum ways to create it? (All this operations to be made in browser and not from code)
You cannot "dynamically" add a column to a table per row. If the user could add a column, then that column would be added to the table in general, and every row in that table would have it. Even if this was possible, it would require granting your application admin rights on your database, which is a huge security faux pas. The database user exposed to the web should have only the most minimal privileges necessary: usually just INSERT, UPDATE, SELECT, and DELETE, and sometimes not even all of those. Anything more puts you at huge risk of SQL injection attacks and similar by malicious users. This is database 101 stuff, so it may behoove you to step back and learn more about the platform you're developing on before proceeding.
It's sounds like you're basically just want something similar to a "settings" table. The way these things normally work is store the name of the "setting" and a value for that as a string. You might also store a type value, also as a string. Then, after you retrieve the setting you can coerce the value into the proper type you need it as. That's really the best you can do with "dynamic" things, since a relational database is very much static. It needs to know the data and the types of that data it's going to handle in advance.

Is this a good approach to select the database based on the user?

I'm developing a system using ASP.NET MVC + WebAPI + AngularJS which has the following property: users can log in and different users have totally different data. The reason is simple: the system allows management of data, but although the schema is the same for everyone, the data is totally disconnected between users. Even because of organization, consistency and security, each user would need one separate database.
This gives rise to a problem: although every single database should be the same, i.e., same tables and columns, and hence same EF Data Context, the connections are different. This confuses me because I'm used to specify the connection string on the config XML file and this couldn't be done here, since the connection string would be dynamic.
I've then thought about a solution, which I doesn't now if it's the best one: I create one repository, which in it's construction receives the username of the logged in user. Then, the repository goes on the database of the system and looks for the connection data for that logged in user (this data would be informed when the user registers). Then the repository builds then connection string and feeds it into the DbContext.
Is this a good approach to this problem? Or there are more recommended ways to deal with this kind of thing? Security is one important concern here, and because of that I'm unsure of my approach.
Each Data Context in an Entity Framework solution has a constructor overload that allows you to specify a connection string. You can find out how to build and use that connection string at the link below.
Reference
How to: Build an EntityConnection Connection String
That said, unless you have very special requirements, it's much better from a maintenance and operational standpoint to simply put a UserID in the appropriate tables, and filter on the currently logged in User ID.
One database per user seems like a crazy solution to me.
Include a user_id column in tables that contain per user data and filter on it appropriately.
I think this depends on how complex your per-user database will be. If we are talking about 5-10 tables, then it is easier to add, manage and query addition ID column for all tables, than it is to manage multiple databases. But the more complex the model will get and the more tables will be in the database, then it becomes much easier just to have one database per user compared to having one more column for each table and having to add the user checks to all your queries. Especially the more complicated ones.
Same goes for performance. If you are expecting user databases to grow large in volume of data, then having separate databases could allow you to scale horizontally by putting different databases into different servers.
Shared database will also pose a problem if user requests raw access into their data. And it can happen, for example when they want to migrate the data.

What is dbo in dbo.Sometable

In my local or on a dedicated server, when i create a table i see the table name as follows:
dbo.Foo
As i was given a database account from some plesk environment, the tables which were created get the name :
mydbuser.Foo
How does prefix matter for my code? or If i create a table/ restore one from my backup, should i expect weird results?
dbo is the default schema that is assigned to a table when you create a table and don't assign a schema explicitly. A database schema is a way to logically group objects such as tables, views, stored procedures etc. You can read more about schemas here
How does prefix matter for my code?
If you don't specify schema in the code, then it will take dbo as default. Though if you have a table with schema other than dbo, then you will have to specify in your code as well, otherwise it won't execute.
If i create a table/ restore one from my backup, should i expect weird results?
Schemas are not evil. If you specify them correctly, everything should be fine.
dbo
It is schema. If no default schema is defined for a user account, SQL Server will assume dbo is the default schema.
As per MSDN
SQL Server 2005 introduced the concept of database schemas and the
separation between database objects and ownership by users. An object
owned by a database user is no longer tied to that user. The object
now belongs to a schema – a container that can hold many database
objects. The schema owner may own one or many schemas. This concept
creates opportunities to expose database objects within a database for
consumption yet protect them from modification, direct access using
poor query techniques, or removal by users other than the owner.
To create your own Schema, you can use following script:
CREATE SCHEMA [EnterSchemaNameHere] AUTHORIZATION [dbo]
You can use them to logically group your tables, for example by creating a schama for "Financial" information and another for "Personal" data. Your tables would then display as:
Financial.Foo
Personal.Foo

Modifying ASP.NET Membership Schema

So I'm using Forms Authentication on my site, and I've set up all the tables and stored procedures in SQL Server. The only thing is, I really don't think I need all these tables, and I'm not a big fan of the table names either.
For instance, I'm using the authentication for employees, so it would be nice to change the table name from "aspnet_Users" to "Employees". And I don't really need the Personalization tables. But I don't know if that would break anything.
Is it possible to modify/delete tables and stored procedures without messing everything up?
Steven, I take it you ran the aspnet_regsql.exe command line tool to add these database objects? Alternatively, you can add just the necessary tables/views/stored procedures for different parts of Membership by running the applicable SQL scripts, which you'll find in the %WINDIR%\Microsoft.Net\Framework\version folder (where version is the .NET version you are using, like v4.0.30319).
There you'll find files named InstallCommon.sql, InstallMembership.sql, InstallRoles.sql, InstallProfile.sql, InstallSqlState.sql, and so on. You'll need to run InstallCommon.sql and then just those other files you need. So if you need just Membership and Roles, you'd run InstallCommon.sql, InstallMembership.sql, and InstallRoles.sql. In this way your database would not include the tables/views/sprocs for profile, SQL state, and so on.
All that being said, I'd just leave in all of the database objects that ASP.NET added. It's probably more work than it's worth to add just the subset of interest and, who knows, you may need to implement profile or Health Monitoring later so why not have these other database objects in place and
ready to go.
And to answer your first question - No, there is no way to change the table name from aspnet_Users to Employees. However, it's not uncommon to create your own table (perhaps called Employees) that stores information about an employee. This table, then, would have a foreign key back to aspnet_Users that links an employee to a particular login account. See Storing Additional User Information for a look at how this can be accomplished.
Happy Programming!
Why not write a simple SqlMembershipProvider?
Edit: No, the default providers expect that schema. I would not recommend modifying it.
Have you considered just leaving the authentication stuff in it's own database?
You can change all references to aspnet_Users to Employees in the .sql scripts mentioned by Scott Mitchell but it isn't recommended. The Membership / Roles API uses stored procs. So if you don't change storedProc names you will be fine.
The issues might be if any future changes to membership / Roles providers and/or API.
Also say in future you need to give access to some users who are not the Employees, the renaming will lose its meaning.

Categories

Resources