cannot open user default database. login failed error - ado.net

I am getting this "cannot open user default database. login failed" error. What I did was using ORM to create DataContext, in the code first call TableExists function to check if the version_tbl existed, if not, then call scripts to exec sql commands to create version_tbl. Then create a new dataContext, but problem is after the call I am getting this error on dataContext entity. If I remove the TableExists call, then dataContext creation is fine or move the dataContext creation before the TableExists call, but then the problem occurs in the TableExists call when it tries to connect. Seems like I can only connect once. Anyway I can call TableExists then able to create dataContext?
Below is my code sample
static bool TableExists(string tableName)
{
using (SqlConnection connection = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=planning;Integrated Security=True"))
{
string checkTable =
String.Format(
"IF OBJECT_ID('{0}', 'U') IS NOT NULL SELECT 'true' ELSE SELECT 'false'",
tableName);
SqlCommand command = new SqlCommand(checkTable, connection);
command.CommandType = CommandType.Text;
connection.Open();
bool retVal = Convert.ToBoolean(command.ExecuteScalar());
return retVal;
}
}
myFunc ()
{
if (!TableExists ("version_tbl"))
{
// call scripts to create version_tbl
}
DataContext ctx = new DataContext ();

Before everything else did you check if your domain user has the appropriate DB rgihts?
Try to validate the DB connection first.

You should be able to open two connections to the database at the same time: 1 through ADO.NET and 1 through LinqToSql.
The format of your code as displayed by StackOverflow is difficult to read, but it appears that you are returning from your TableExists method before the using statement is able to close the connection. Does it make any difference if you change that?
Are you getting different errors depending on which order you open the connections or is it always the same error?

Don't stop with the Exception. Go to the database and check the message in the log. The exceptions for LOGIN's are not clear on purpose for security reasons, but the log should have a better explanation of what happened.

Related

Handling Errors with db.Database.SqlQuery

I came across an issue today where I had a query that was failing. I am using db.Database.SqlQuery<T>() to query another applications data. We have a custom view over their data. Today the admin rebuilt the indexes in the software and in the process deleted the custom view. While that is an issue that SO can't solve, the issue you can help with is gracefully handling the case where the view no longer exists.
For the main application, we are using this data as supplemental data. Meaning that it isn't critical to have the information display if the server or table can't be reached. The query is run in the follow WebApi action (I added a few comments based on my observations while debugging.):
public Task<HttpResponseMessage> GetByAddress(string id)
{
Task<HttpResponseMessage> response;
string sql = // my sql statement;
List<object> parameterList = new List<object>();
parameterList.Add(id.ToUpper());
object[] param = parameterList.ToArray();
// This is worthless since the following line will completely replace this
IEnumerable<CallsForService> calls = new List<CallsForService>();
// If the table does not exist, this does not throw an error, instead it creates a different object with the error details.
calls = db.Database.SqlQuery<CallsForService>(sql, param);
response = Task.FromResult<HttpResponseMessage>(Request.CreateResponse(HttpStatusCode.OK, calls));
return response;
}
My question then is how do I check for these errors and at least gracefully send back to the calling application an empty list. I can then log these errors with ELMAH so I can catch the issue and get it fixed.
The query is not executed until the results are enumerated, so you can just count the number of records returned and make it raise an error if there any.
calls = db.Database.SqlQuery<CallsForService>(sql, param);
var recCount = calls.Count();
Any errors raised after the last line will be caught by the try/catch block.

Entity Framework 4.0 - The underlying provider failed on Open

We have a web application with Entity Framework 4.0. Unfortunately, when the large volume of users hit the application the EF throws an error
The underlying provider failed on Open
Below is the code snippet:
//DAL
public IQueryable<EmployeeEntity> GetEmployeeDetail()
{
DatabaseEntities ent = new DatabaseEntities(this._connectionString);
IQueryable<EmployeeEntity> result = from employee in ent.EmployeeEntity
select employee;
return result;
}
Please note the above code returns IQuerable.
Is anything wrong with above pattern that could cause the exception to occur?
When and how does Entity Framework determine to close / open db connection and also how long to retain?
On what scenario does above error occurs?
What's the maximum number of connection pool for EF and how do we configure?
Do we need to explicitely specify open and close
Is code below a best way to resolve above issue?
public IQueryable<EmployeeEntity> GetEmployeeDetail()
{
using (DatabaseEntities ent = new DatabaseEntities(this._connectionString))
{
IQueryable<EmployeeEntity> result = from employee in ent.EmployeeEntity
select employee;
return result.ToList().AsQuerable();
}
}
The ToList() call will cause the query to run on the database immediately and as this is not filtered in any way will return every employee in your database. This is probably likely to cause you performance issues.
However you can't remove this in your case because if you return the IQueryable directly then the context will be disposed by the time you try and fetch results.
You could either:
change the way it works so that the scope of ent does not end when the method returns and return the query without calling ToList(). You can then further filter the IQueryable before calling ToList().
call ToList() within the method but filter/limit the query first (e.g. pass some parameters into the method to specify this) to reduce the number of rows coming back from the database.

Manage Transactions on Business Layer

I want to use TransactionScope class in my business layer to manage database operation in data access layer.
Here is my sample code. When i execute it, it tries to enable the dtc. I want to do the operation without enable dtc.
I already checked https://entlib.codeplex.com/discussions/32592 article. It didn't work for me. I read many articles on this subject but none of them really touch enterprise library or i didn't see.
by the way, i am able to use TransactionScope using dotnet sql client and it works pretty well.
what would be the inside of SampleInsert() method?
Thanks,
Business Layer method:
public void SampleInsert()
{
using (TransactionScope scope = new TransactionScope())
{
Sample1DAL dal1 = new Sample1DAL(null);
Sample2DAL dal2 = new Sample2DAL(null);
Sample3DAL dal3 = new Sample3DAL(null);
dal1.SampleInsert();
dal2.SampleInsert();
dal3.SampleInsert();
scope.Complete();
}
}
Data Access Layer method:
//sampleInsert method structurally same for each 3 dal
public void SampleInsert()
{
Database database = DatabaseFactory.CreateDatabase(Utility.DATABASE_INFO); ;
using (DbConnection conn = database.CreateConnection())
{
conn.Open();
DbCommand cmd = database.GetStoredProcCommand("P_TEST_INS", "some value3");
database.ExecuteNonQuery(cmd);
}
}
Hi yes this will enable dtc because you are creating 3 DB connections within one TransactionScope . When more than one DB connection is created within same TransactionScope the local transaction escalate to Distributed Transaction and hence dtc will be enabled to manage Distributed Trnsactions.You will have to do it in a way that only one DB connection is created for entire TransactionScope. I hope this will give you an idea.
After research and waching query analyzer, I changed the SampleInsert() body as follows and it worked. The problem was as ethicallogics mentioned opening new connection each time i access the database.
public void SampleInsert()
{
Database database = DatabaseFactory.CreateDatabase(Utility.DATABASE_INFO);
using (DbCommand cmd = database.GetStoredProcCommand("P_TEST_INS", "some value1"))
{
database.ExecuteNonQuery(cmd);
}
}

Managing transactions between EntityFramework and EnterpriseLibrary's DatabaseFactory

I'm working with an existing set of code that manages multiple database updates in a single transaction. Here is a simplified example:
Database db = DatabaseFactory.CreateDatabase();
using (DbConnection dbConnection = db.CreateConnection())
{
dbConnection.Open();
DbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
//do work
dbTransaction.Commit();
}
catch (Exception ex)
{
dbTransaction.Rollback();
}
}
I am also using EntityFramework in this same project for new development. Below is a simplified example of the usage of my repository class:
List<ThingViewModel> things = new List<ThingViewModel>();
// populate list of things
IObjectRepository thingRepository = new ThingRepository();
thingRepository.AddThings(things);
thingRepository.Save();
I want the work done in 'AddThings' to happen as part of the transaction in the first block of code.
Is there some clean way of blending my repository pattern into this existing code or vice-versa? I'm not at the point yet where it is feasible to rewrite the existing code to be entirely within EntityFramework, so I'm looking for some some interim approach.
I have tried passing the transaction from the older code into the repository, and thus EntityFramework, but that does not seem to work. I have also tried passing the ObjectContext back out to the older code in order to enlist it in the transaction. Neither approach works.
I cannot believe that I am the first person to encounter this hurdle in migrating existing code to EntityFramework... there must be something I am not considering.
I'll list the things that I have tried below:
using (TransactionScope transactionScope = new TransactionScope())
{
Database db = DatabaseFactory.CreateDatabase();
using (DbConnection dbConnection = db.CreateConnection())
{
dbConnection.Open();
DbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
//do work
dbTransaction.Commit();
}
catch (Exception ex)
{
dbTransaction.Rollback();
}
}
Thing thing = new Thing(){
Prop1 = Val1,
Prop2 = Val2
};
ThingObjectContext context = new ThingObjectContext();
context.Things.AddObject(thing);
context.SaveChanges();
transactionScope.Complete();
}
This last example 'works', it does not function as a transaction. When the EF insert fails, the EL commands are not rolled back by the TransactionScope. If I don't put those explicit calls to .Commit() and .SaveChanges(), nothing happens. I would really like for this to share the same connection if possible. Two other variations of this I am currently playing around with is trying to use the same connection between both EF and EL as well as use EnlistTransaction on one side or the other. Definitely trying to keep this from becoming a MSDTC - don't want the extra overhead associated with that.
Use TransactionScope instead of explicit transaction management. You'll simplify the overall code and everything you do should automatically detect and use the same transaction.
Is there any way you can call Database.GetOpenConnection() instead of CreateConnection() in your EL code, and pass in the things.Connection that you create inside of a TransactionScope block? I haven't tested this, but that is what I would try first.

Run a Stored Procedure via a click of a button in .Net web page

Afternoon All,
I have a stored procedure in an SQL 2005 database named GasNominationsRawData_Insert.
When executed this simply extracts some data from another database and inserts the result into a table. This query works fine.
What i need to do is enable this to be executed on the click on a button on my web page. I have had a good luck around the internet have have managed to create the following code in my .net 2008 web page. But i think im either missing something or i have have completly the wrong code. Im new to programming in .Net but i understand that i need to delclare the stored procedure, create the SQL connection, create the command line, open the conection, execute the query and then close the connection.
I dont need or have any parameters. Essentially this button is just used to push data to a table.
Imports System.Data
Imports System.Data.SqlClient
Partial Class RawData
Inherits System.Web.UI.Page
Protected Sub btnAddRawData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddRawData.Click
'Declare Stored Procedure
Dim GasNominationsRawData_Insert As String = "GasNominationsRawData_Insert"
'Declare SQL Connection (This is the connection string located on the web.config page)
Dim SQLConn As SqlConnection
SQLConn = New SqlConnection("GasNominationsDataConnectionString")
'Declare command
Dim SqlComm As SqlCommand = New SqlCommand("GasNominationsRawData_Insert", SQLConn)
SqlComm.CommandType = CommandType.StoredProcedure
Try
'Open SQL Connection
SQLConn.Open()
'Execute Query
SqlComm.ExecuteNonQuery()
'Close connection
SQLConn.Close()
Catch ex As Exception
Throw (ex)
End Try
End Sub
End Class
Any Help is much appreciated.
Regards Betty
Upps. I overlooked that. You're trying to connect to your database with the connectionstring: "GasNominationsDataConnectionString". That's of course no correct connection string.
Your connection string should look somehow like that:
"Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;"
So you have to get your connection string first out of your web.config like
Dim GasNominationsDataConnectionString As String = ConfigurationManager.ConnectionStrings("GasNominationsDataConnectionString").ConnectionString
Regards
Anja
Looks fine at a first glance. So what happens on clicking the button? Have you assured that your btnAddRawData_Click is called when the button is clicked?