Servicestack OrmLite - Execute as User/Impersonation - c#

I am using Servicestack OrmLite as a data layer for my application (.NET C# 3.5/SQL Server).
One of the design requirements (It isn't greenfield, so it is mandatory) is to have commands executed as a particular user which has a schema attached on the SQL server side.
After creating the DbContext with OpenDbConnection() I send an Execute as User command to SQL server so that they are executing with the correct login, and they are switched over to the correct schema for that login.
The error I am getting back for selects against that connection later in the process is:
A severe error occurred on the current command. The results, if any, should be discarded.
Thoughts:
Connection pooling is losing the current user command sent to SQL server?
Is there a built in User/schema handler extension to OrmLite that I haven't seen?
RegisterConnection?
Thanks for your input.

Related

Can't initialize local SQL Server database with EFCore commandline tools

I've been trying to follow several different tutorials with EFCore and .net core and I've been totally blocked at the point where I try and create a local database.
I've used both the powershell tools and the commandline tools to try and create an initial migration (or do anything, really).
I consistently get the error:
System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - No process is on the other end of the pipe.)
The database does not currently exist on the system, though local SQL Server appears to be up and running.
Here is the c# code for adding the context:
services.AddDbContextPool<TestDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("TestDb")
)
);
This is the connection string code:
"TestDb": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=TestDb"
I get similar errors whether I run add-migration, dotnet ef migration add, or dotnet ef dbcontext info. (note: with the dotnet calls I am using the -s ..\{webproject}\{webproject}.csproj property
I've also messed with the connection string by adding various combinations of Trusted_Connection=True; MultipleActiveResultSets=True;, and Integrated Security=true.
I've gone into SSMS and ensured the Server authentication is SQL Server and Windows Authentication Mode and that Maximum Connections is set to 0 (unlimited). I've also gone to logins and tried adding the user to pretty much all the server roles.
So, yeah, I'm pretty confused. I've worked with EF for years, though this is my first experience with EFCore and I'm definitely more of a developer than a SQL Admin. This is also my first time trying to use the local db on this particular computer.
Edit: Looking at error.log in AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\mssqllocaldb I see this error:
2020-01-28 10:15:03.50 Logon Error: 18456, Severity: 14, State: 38.
2020-01-28 10:15:03.50 Logon Login failed for user 'LAPTOP-NC6HQ4TB\ripli'. Reason: Failed to open the explicitly specified database 'TestDb'. [CLIENT: <named pipe>]
Which is confusing. Of course I can't open the specified database. The entire point is I want to create a DB that doesn't yet exist.
Found the answer. Sorry to everyone who tried to help, as you wouldn't have had enough information to solve it.
In the DbContext I had tried to add some code to the constructor to try and populate some data to the database as part of a test. This caused several problems. If the Database hadn't yet been created it tried to connect to the DB before it had been created, which caused the problems I described.
Furthermore, if I had created the db manually it would try to access the DbSets (which had not yet been created), and then complain that the set name was invalid (which, at this point it was.
This all might have been fine if the DB had been created in advance, but since I was using the DbContext to construct the database, it understandably caused problems.
And all of this headache would have been avoided had I not violated SRP and not tried to (even temporarily) hijack a context constructor to hack in some test data.
The takeaway here? Don't pollute your constructors with unrelated hacks. Bleh.

U-SQL data source as SQL Server inside a UDF

I need to extract rows from a SQL table where some columns are encrypted using SQL Server's new 'Always Encrypted' feature. I see that I cannot use the 'AZURESQLDB' DataSource feature and there needs to be decryption done before reading the data in plain text. Are there plans to add this capability?. Meanwhile, I tried to write a user defined function that will do the same operation(connect, decrypt data and return object) in a registered assembly but when it runs, I get the following error:
Inner exception from user expression: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I have checked the code and everything seems correct. The connection string is used by the SqlConnection object and works fine in all other applications. I am guessing that the connectivity to external data sources from within a UDF is blocked. Is there any way around this?
Are you using the DATA SOURCE in U-SQL for representing your SQL Server instance and you cannot get it to read encrypted data? If so, please file a feature request at http://aka.ms/adlfeedback.
You cannot call out to network resources directly from within U-SQL user code for the reasons explained here.
One way around this might be to create a stored procedure which does the hard work, the decryption then renders the data. Then use Azure Data Factory with a Stored Proc Task to access the decrypted data and move what you need to the Data Lake - not including the secure data. From there you could then access it using a U-SQL script. One idea? Let me know if you need me to work up more of an example.

How to avoid distributed transaction?

There is a C# program calling a stored proc which has insert linkedserver... from ..... The C# program using Entity framework (ctx.Database.ExecuteSqlCommand("....")).
I've tried
Change the property "Enable Promotion of Distributed Transaction" to false.
Add "Enlist=false" in the connection string of the C# program
Change the MSDTC of the SQL server to allow anonymous authentication...
But it still gets the following error.
A severe error occurred on the current command. The results, if any, should be discarded.
OLE DB provider "SQLNCLI11" for linked server "...." returned message "No transaction is active.".

Asp.Net MVC3 Ado.Net Entity Data Model timeout error - Entity Framework Command execution timeout error

First let me clarify, I searched stackoverflow solutions for this, and whatever I found didn't resolve this error in my situation. Users keep getting this error every now and than and when they re-query or refresh the page data appear fine without error. This behavior is certainly irritating the users even if they get a user-friendly message instead of Asp.net YSOD.
Complete error message:
System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
To give a brief overview about the application: It's a .Net MVC3 application. There is separate project for Business logic and separate project for UI (Controller and Views etc..). Business logic project contains Data layer which is ADO.NET Entity Data Model (I believe entity framework 4.1). The EF contains only Sql Server Store Procedures (there are no tables/views etc..). All communications to the database happen through SPs function imports. The business project queries the SPs and returns IQueriable type business object, which eventually we use in controller and return as JSON objects to the jQuery AJAX call. Our SQL serve DB is 2012.
One solution resolves this issue temporarily is when I restart the IIS 7.
What I have tried so far and have not been able to resolve this issue:
Increased EF Command Execution timeout.
used below using pattern
using (DbContext context = new DBContext())
{
context.Connection.Open();
//All EF code goes here.
context.Connection.Close();
}
Updating the model from DB and recreating all the function imports fresh.
Database side tuning up to improve the query performance.
Some more...unable to recall right now.
Please let me know if you need any other information. Any help will be very much appreciated.

Use Linq to Sql without connection

I was reading that linq was lazy and that it did not executed the query until it needed to.
if that is the case why does this code fails:
var db = new Data.DataClasses1DataContext(#"Data Source=.\sqlexpress;Initial Catalog=MyDb;Integrated Security=True");
var companies = db.Customers.Where(x => x.Company=="Foo");
var query = companies.ToString();
if I run that code in a computer that does not have sql server installed it will not run why? I am not doing any statement that needs data. If I would call companies.ToList() then its ok for the code to fail. Is there a way I can make use of Linq to SQL Classes without using a connection. I know the moment I do ToList() or try to enumerate through the results I will get an error. I just want to use Linq to Sql Classes in order to generate the SQL statements and see them as a string.
I have a client and a server. The server is a WCF service and the client is a console application. I will send the query encrypted for cases where the user is not entering it. I will like to generate my queries using Linq to Sql classes it does not make sence I have to install sql server on the client just so that I can generate the queries.
My temporary solution is to create a second database on the same server. That database will be allowed to accept remote connections and the whole purpose of it is so that the line
var db = new Data.DataClasses1DataContext(#"some remote connection string");
works. Once I initialize that line I will never need the connection again. It makes no sense.
Do not generate queries on the client then pass the SQL to the service. Instead, generate the lambda expression on the client, and send the expressions to the service.
See "How can I pass a lambda expression to a WCF service?".
One problem this will solve is that of database and schema versioning. TO do it your way would require that the client understand the database schema and even database version, and that it be the same (or compatible) with that which the service uses. Otherwise, you would be stuck having the SQL for one version of SQL Server generated on the client, then sent to a different SQL Server version on the service (or equivalently, a different database schema).
The problem is in the creation of the db context object and not in the linq statement. Specifically, in order to create the db context object you need an actual connection string. If you don't provide one, then the db context you try to create, I suppose it would be null or you will get an exception. Then defining your linq query using this null object will throw an exception, even if your query doesn't use the ToList(), which will definetely force the execution of your linq query.
Reading again your post I believe that you should define in the connection string the sql express server that is installed in the server, which will host the WCF service. Then the client having this connection string would have the ability to make calls to your server database.

Categories

Resources