Microsoft Enterprise Lib - LoadDataSet Method close connection - enterprise-library

We have been using Microsoft Enterprise Lib for data access, some old legacy code and are using LoadDataSet method. Does this method close the db connection or do we have to explicitly close open connections?

The LoadDataSet method will close the Database connection before returning. First an open connection is returned, then the DataSet is filled and then the connection is closed (actually Disposed).
You can see this in the source of Database.cs:
public virtual void LoadDataSet(DbCommand command,
DataSet dataSet,
string[] tableNames)
{
using (var wrapper = GetOpenConnection())
{
PrepareCommand(command, wrapper.Connection);
DoLoadDataSet(command, dataSet, tableNames);
}
}

Related

Entity Framework DefaultConnectionFactory being ignored

I'm using Entity Framework 5 with Code First. I've written a custom IDbConnectionFactory which I want to use for all the connections made by my DbContext class, so early on in the application's lifecycle, before any database work is done, I call
Database.DefaultConnectionFactory = new MyConnectionFactory();
However, MyConnectionFactory.CreateConnection is never called, which suggests to me that EF's changed it back - but the debugger shows that it's still a MyConnectionFactory after several queries have run. For some reason, it's just not using it.
My DbContext is initialised by passing the name of a connection string from the app.config file, and those connection strings do specify an explicit provider (as indeed they have to) so I'm wondering if that's causing a per-connection override of the connection factory based on the connection string. Does this happen and can I stop it without registering a completely new provider (although maybe that's not too hard to do?).
Whatever I see online about this (much obscured by the defaultConnectionFactory tag in various app.config examples) suggests you can just change it to an IDbConnectionFactory instance of your choice and it'll work, but mine isn't behaving.
The purpose of this is to allow me to run a particular set of SQL statements whenever a new connection is opened, so the second part of this question would be does anybody know a better way to do this?
I know it is not ideal but this worked for me:
public class DBBase : DbContext
{
public DBBase(string nameOrConnectionString)
: base(Database.DefaultConnectionFactory.CreateConnection(nameOrConnectionString), true)
{
}
// ...
}
You need to get the connection that you built for each call that you are wanting to use. For example using the following code.
private static void UsingCustomConnection()
{
using (var conn = Database.DefaultConnectionFactory.CreateConnection("YourDbName"))
{
using (var context = new YourContext(conn))
{
context.Destinations.Add(new Destination {Name = "Colorado"});
context.SaveChanges();
}
}
}
You will need to setup this in YourContext
public YourContext(DbConnection connection)
: base(connection, contextOwnsConnection: false)
{
}

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);
}
}

iPhone - Connection String and DB File

I am developing a iPhone app using Monotouch. I need to access a Sqlite DB. In my soultion, I have a contracts, data access, business access and UI project. I have two questions:
Where should I keep my DB file? Originally, I put it in the data access project. When I compile my business access project it copies the DB file to the output, but when I compile my UI project it does not (UI has a reference to business access which has a ref to data access). I moved it to the UI project, but it feels wrong to keep it there.
Where should I keep the connection string to the DB? Is there a concept of config files?
Here is what we do:
We ship a copy of the DB in the application. It is included as Content, Always Copy in the project.
On the user's machine, it is stored in the special directory Environment.SpecialFolder.Personal.
When the app is started, we check to see if the database exists on the user's system and, if not, copy it there.
The connection string is just "Data Source=" + sDatabasePath.
Here is a sample of the code that we use for this (I hacked in the connection stuff since we use a homebuilt class for managing the DB, but you should get the idea):
const string DATABASE_FILE_NAME = "MyDB.db3";
bool fSuccess = false;
DbConnection conn = new DbConnection ();
string sApplicationDir = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "MyApplicationSubDir");
if (!Directory.Exists (sApplicationDir)) {
Directory.CreateDirectory (sApplicationDir);
}
// Generate the directory to the database file
string sDatabaseDir = Path.Combine (sApplicationDir, "Database");
m_sDatabaseDir = sDatabaseDir;
if (!Directory.Exists (sDatabaseDir)) {
Directory.CreateDirectory (sDatabaseDir);
}
// Generate the path to the database file
string sDatabasePath = Path.Combine (sDatabaseDir, DATABASE_FILE_NAME);
m_sDatabaseFile = sDatabasePath;
// If the file does not not exist
if (!File.Exists (sDatabasePath)) {
// Copy the base implementation
File.Copy (Path.Combine (Path.Combine (Environment.CurrentDirectory, "Database"), DATABASE_FILE_NAME), sDatabasePath);
}
// Initialize the DB
conn.ConnectionString = "Data Source=" + sDatabasePath;
out of interest, have you looked at sqlite-net ? http://code.google.com/p/sqlite-net/
Makes your DB handling a lot easier.

Different Connection Strings with Entity Framework based on Context

I have a web forms application that uses entity framework, the application is deployed on a development box, my local machine and a production box. Each of these have different connection strings.
What is the best way of handling this.
I use TFS Build Server to deploy to development and take the result of that build zip it and copy it to production manually.
I also use Web Deployment Projects if that helps
What I was doing before was when the ORM started it would choose a connection string based on the name of the root folder. With Entity Framework I don't know how to do this without having to set it on every page.
We have something vaguely similar, I created a class to wrap the EntityContext object, which sets the connection string appropriately - you'd need something similar, based on how you set your connection string:
Public Class MyEntityModel
Private _dataContext As Entities
Public Sub New()
Dim entityBuilder As New EntityConnectionStringBuilder()
entityBuilder.ProviderConnectionString = MyApplicationConnectionString
entityBuilder.Metadata = "res://*/"
entityBuilder.Provider = "System.Data.SqlClient"
_dataContext = New Entities(entityBuilder.ConnectionString)
End Sub
Public Function DataContext() As Entities
Return _dataContext
End Function
End Class
FYI You can use config transformations now in VS 2010:
http://msdn.microsoft.com/en-us/vstudio/Video/ff801895

cannot open user default database. login failed error

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.