I'm currently trying to distribute a application that relies on some form of database in .NET. I am trying to use SQL Server Express or SQL Server Express LocalDB.
For accessing the database I am using the entity framework.
Now the target is to create a deployable version that does not require any alterations on the SQL server by hand. It needs to install and setup as far as needed to launch the application. All goes well on my development computer. How ever once deploying to another computer the problems begin.
I tried the LocalDB in order to avoid the requirement to setup the database structure by hand on the target machine. How ever upon launching the application its reports a problem with the connection string. The attachdbfilename is not valid.
This filename is set to attachdbfilename=|DataDirectory|\database\Db.mdf
As I said. On my development maschine this works. Both when using the deployed files and when running it from the IDE. Yet the target mashine reports the problem. I installed the SQL Server Express 2012 LocalDB using ClickOnce along with my application. The deployed files contain the mdf file in the proper directory.
The full connection strings are:
<connectionStrings>
<add name="DbContainer" connectionString="metadata=res://*/database.DbModel.csdl|res://*/database.DbModel.ssdl|res://*/database.DbModel.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\database\Db.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
I fail to see a reason why the attachdbfilename is not valid. The installation of the sql server on the target machine seems to be okay.
I also tried to pulish it with the normal SQL Server 2012 express. How ever I assume if I want to use this, without a attached database file I need to create the required database by hand. And that is not a option.
I read in some questions that this indicates a problem with the create ObjectContext but this one is looking good as well:
Public Partial Class DbContainer
Inherits ObjectContext
Public Sub New()
MyBase.New("name=DbContainer", "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connectionString As String)
MyBase.New(connectionString, "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connection As EntityConnection)
MyBase.New(connection, "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
...
Just like it got generated by the entity framework.
I am running out of ideas on how to solve this problem.
Okay the problem turned out to be the |DataDirectory|
I replace this entry in the connection string by hand using the proper one click data directory I optained using:
Dim dataDir As String
If ApplicationDeployment.IsNetworkDeployed Then
Dim ad = ApplicationDeployment.CurrentDeployment
dataDir = ad.DataDirectory
Else
dataDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
End If
No problem loading the database file anymore. I can't say why the replacement of the |DataDirectory| is not working. For the version on the development computer this is simply replace with a empty string... and this works because the working directory is the parent of the refered database directory.
How ever when using ClickOnce the data files, including the database, is located in a different directory. This causes the connect string to fail. The code above fixes this problem. I can't explain for what reason this is not working out of the box.
Related
My client/server application is written on VB.NET and it uses sqlite3 (*.db3) database. Everything was working fine with the old .db3 database unless I had to delete it and make a new one. I am using SQLite Maestro to create the database, import tables and data and that's it, but for some reason server won't read the database anymore saying that "file is encrypted or it's not a database file". Alright, what just happened? This is an old project from 2012, I remember all I did was just create the database in Maestro, add the tables and the data and it was all working like a charm. Now doesn't work doing exactly the same thing! I though that they changed something and Maestro is creating db's differently now, so I tried to use older version, but it's not possible to use older version of the program. I noticed that whenever I create a fresh database and attempt to use it with the server and every time it shows the error message that the file is encrypted or it's not a database then the database is corrupted. I can't open it in SQLite Maestro anymore. What should I do ?
Don't know if this matters, but here's the code that reads the database:
Private Shared ReadOnly connectionString As String = String.Format("Data Source={0};version=3;", ReadDatabasePath())
Private Shared connection_ As New SQLiteConnection(connectionString)
Public Shared ReadOnly Property Connection() As DbConnection
Get
Return connection_
End Get
End Property
I am using Visual Studios build-in DataSource functions, to work with my application and its database. Now I am facing one little problem; How do I change the database-server in the final project?
Obviously the end-users server name will not be the same as mine.
Also how can I change it at runtime? My application has functions to find the database-server itself, so it needs to be able to change the database server at runtime (Only at applcations start) .
Update 1:
Right now I am Changing my TableAdapter.Connection.ConnectionString with .Replace("My Local Server Name", "New Server Name") to change the Server. But I don't think that's the way it's supposed to be done.
If you want to change the connection string after deployment then you edit the config file by hand or you can do so in code if the current user is an administrator.
If you want to change the connection string for a table adapter at run time to something other than what's in the config file then you do indeed need to set the Connection.ConnectionString property. The most advisable way to do that is to use a connection string builder. For an Access database, that might look like this:
Dim builder As New OleDbConnectionStringBuilder(myTableAdapter.Connection.ConnectionString)
builder.DataSource = dataSourceName
myTableAdapter.Connection.ConnectionString = builder.ConnectionString
MVC5, EF 6.0 Code First, SQL
I have a remotely hosted MVC5 website using an SQL database. My objective is to easily code up to copy or copy/delete certain records out of the hosted database to a local database. So I added an additional context to my development project as shown.
Public Class WebDbContext
Inherits DbContext
Public Sub New()
MyBase.New("name=WebDbConnection")
Me.Configuration.LazyLoadingEnabled = True
End Sub
Public Shared Function Create() As WebDbContext
Return New WebDbContext()
End Function
Public Property table1 As DbSet(Of Class1)
.
.
Public Property tableN As DbSet(Of ClassN)
End Class
and in web.config I added the connection string
<configuration>
.
.
<connectionStrings>
<add name="WebDbConnection" connectionString="Data Source=<ip>;Initial Catalog=<dbname>;User ID=<id>;Password=<pwd>;" providerName="System.Data.SqlClient" />
</connectionStrings>
.
.
This new context allows me to access and manipulate the website database from the development project. I will clearly need another context for the database I want to save locally, but I'm just getting started with this. I started in this direction because the Class definitions for the new context will always be up to date with the hosted database since the development project originates the Class definitions that are in the hosted database. Is there a better way to code this access to the remote database?
But my real question is: What might I expect with regard to this new WebDbContext when my next add-migration happens? Does each context create an EF add-migration requirement, or is it just the Class definitions that create the add-migration requirement and the additional context(s) won't be a problem?
Regarding access of the production database from the development project, I recognize we treat production databases differently, but this project is in early development and a quick programmatic solution is being sought. I understand at a later time when production is underway a different solution may be necessary.
Or, of course as often is the case, if there's a completely different and generally accepted way to accomplish my objective as stated at the outset, what might that be?
Not too sure if I'm fully grasping your question, but if I get the gist of your question, your trying to have 2x databases (1 localdb + 1 SQL server hosted) and want to know how to setup data migrations.
First you will need 2x connectionStrings, 1 for local and 1 for SQL
Then in your package manager console you will need to run the commands:
enable-migrations
add-migration -Name firstDbMigrationScript -ConnectionStringName firstConnnectionString
add-migration -Name secondDbMigrationScript -ConnectionStringName secondConnnectionString
Sorry if this stuff doesn't work strait up, I'm coding from memory
probably this is a simple question but because i have never used resources like that i can not think how should i do it.
I am writing a very simple program that connects to a accdb file (Microsoft Access 2007 file) and returns some results in a datagridview. Everything is fine. Now because we have to deploy this program in many computers i publish it so everyone we want can install it and have updates. What i wanted to do is to make the database file part of the program which i did it by adding it to the resources. My problem is that i do not know what connection string to enter in order to access it in my resources.
My previous connectionstring before i deploy it was this
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\bl.accdb;Persist Security Info=True
What should i change in the data source in order to access the same file in my resources? Or am i wrong and this is not possible?
Thanks
You can do it. All you need to do is point the datasource to the location of the resources direcory, which by default is adjacent to the application itself. You could determine this at runtime by using:
Application.StartupPath & "\Resources\DatabaseName.accdb"
I have a program that contains .dbml files. I created this file with Server Explorer.
I want to execute this program on other computers but I seem to be having issues with dependencies because I use LINQ.
How can I fix this?
Can you be more specific? What errors are you encountering? Did you use SQL Passwords or Network authentication? Do your users have network accounts added to SQL? Is this a permission based error?
Just one other possibility: Your users should have .NET 3.51 installed on their systems or they won't get the best possible Linq support. They might not have the Linq assemblies at all.
Yeah, we need more info, but I'm guessing you're having problems with the ConnectionString? as in, there's a connection string in your DBML designer file, and it doesn't match your production DB connection string?
If this is the case, then perhaps write a class that handles all instantiations of your DataContext in your code.
Then, within that class, whenever a new datacontext is created, you override the DBML connectionstring with your current connectionstring, probably from your web.config. this ensures your LINQ stuff is always connected to the correct DB during runtime.
Perhaps something like this (the property names might differ):
Public Shared Function GetNewContext() As YourDataContext
Dim dContext As YourDataContext
dContext = New YourDataContext()
dContext.Connection.ConnectionString = MyConnectionStringFromTheWebConfig()
Return dContext
End Function