First of all, let me state I'm very new to EF. With that said, here's my dilemma:
There will be an ASP.NET App migrated to ASP.NET MVC. I would like to utilize EF for this. There is one main database which stores "client information". Apart from that, every "client" has their own database. These are the constraints we have.
Currently, client information in the main DB that enables me to build a connection string per client and make individual SQL calls.
How would I accomplish the same thing in Entity Framework? Each database WILL have the same schema. Is there a way to programmatically switch the Connection String? These DBs are currently on the same server, but that's not a requirement and it may be a completely different server.
Any ideas?
Multiple connection strings in the Web.config would be a last resort. Even then, I'm not sure how exactly to wire this up.
Thank you in advance.
If you work through an EntityConnection in the constructor of your entities object, you can change the database pretty easily.
EntityConnection con = new EntityConnection(connString);
con.ChangeDatabase(dbName);
using (Entities context = new Entities(con))
{
// Some code here
}
When you build a data context, here's how to programmatically change the connection string at runtime by modifying the Context.Connection property:
//Get the connection string from app.config and assign it to sqlconnection string builder
SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder(((EntityConnection)context.Connection).StoreConnection.ConnectionString);
sb.IntegratedSecurity = false;
sb.UserID ="User1";
sb.Password = "Password1";
//set the object context connection string back from string builder. This will assign modified connection string.
((EntityConnection)context.Connection).StoreConnection.ConnectionString = sb.ConnectionString;
Taken from: http://sivapinnaka.spaces.live.com/blog/cns!B027EF7E7070AD69!211.entry
If the number of your customers is limited and the connection strings hardly ever change, an elegant way might be to use ConfigurationManager.ConnectionStrings to retreive the connection string needed.
Like
string connectionString = ConfigurationManager.ConnectionStrings["Miller"].ConnectionString;
return new Entities(connectionString);
See also
http://msdn.microsoft.com/en-us/library/ms254494.aspx
Related
Currently, I have something like this everywhere in my ASP.NET MVC site wherever I need to connect to RavenDB.
using (var ds = new DocumentStore { Url = urlBase }.Initialize())
{
ds.Conventions.FailoverBehavior = FailoverBehavior.ReadFromAllServers;
}
Is there a way that I can set the FailoverBehavior globally, like perhaps in the web.config, so that I don't have to do this every time I create a new instance of the DocumentStore?
There needs to be one DocumentStore instance in your application per database (initialized usually from global.asax), you never create one from an MVC controller, so your question never begins...
heys guys,
i have a website, which contains lots of db work to display data on page, so i have created a VB class which is public, under App_Code.
Now i have all the methods and functions under that class are Shared(Static), also i have a connection variable which is also static.
Client complains, that sometime there appears an error on the page, one of those error is Field Name does not belong to table Table, i dont understand, about this, as this is very rare, if there is no field with name, then this should occur everytime, one of my colleague says that there should not be Shared methods or functions... is this correct..
There is no "security" problem with a static method. Your colleague is confused. Whether or not the code you wrote should be static or instance methods depends on what exactly it does. But having them as static methods is not "dangerous."
I suggest you track down the query that is causing the problem because the method being static is certainly not the issue.
As far as your connection goes, I would not recommend keeping it as a static variable. I assume this is a SqlConnection, or something similar. In that case, if you keep it as a static variable, it is possible for the following to occur:
Your connection is never closed, even after you're done using it.
You will have issues if you have multiple queries trying to use the connection at the same time.
So I recommend you use the following pattern to ensure your connections are only kept open as long as they are in use.
public void DoSomething()
{
//Doing some work that doesn't need a connection.
//Now ready to submit or fetch data from the database.
using (SqlConnection connection = new SqlConnection(...))
{
using (SqlCommand command = new SqlCommand(..., connection))
{
//Now, working with the connection and command.
}
}
//Done with the connection, doing more work now.
}
The using statement works with anything that is IDisposable. Your connection variable here will be automatically closed and destroyed at the closing bracket of the using statement. I recommend you use it for anything that you can. Streams, SqlConnections, Fonts, etc.
It sounds to me like you have a infrequently-used SQL statement that refers to a column that does not exist on a table.
For example - suppose you had SQL like so
SELECT Col4 FROM Table2
and Col4 was not a member of Table2. You would get the error you describe.
If you're building SQL dynamically (which is dodgey) you might run into this.
But I don't think it has anything to do with your method 'security.'
The ASP.NET web application I am developing needs to support two different types of databases, namely Access and MS SQL Server 2008 Express.
I already have connection strings for each database type stored in web.config, and I have another web.config value that specifies which one to use. So I can get the proper connection string with no problem.
The big problem comes with the database objects. For Access, which I have already implemented, I am using the objects OleDbConnection, OleDbCommand and OleDbDataReader in the code to make the database calls.
It appears that for SQL Server, I can't use those objects, but rather I would need to use the objects SqlConnection, SqlCommand and SqlDataReader to do essentially the same things.
I want to reuse as much of my current code as possible and not have to create two separate blocks for each database type. (I have a lot of methods that take an OleDbDataReader as a parameter - I do not want to have to make 2 of each of those methods, for example.)
I noticed that the connection objects both inherit from DbConnection. And the same is true for the data readers (DbDataReader) and the commands (DbCommand).
Would it be possible to take my existing code for Access, replace all of the Ole objects with the Db objects, and then cast those objects as the proper type depending on the current database type?
Are there any best practices for supporting two database types in one ASP.NET application?
I can add some of my code if that would help. Thanks.
Yes, from framework 2.0 all data readers inherit from the DbDataReader class, so your methods could take a DbDataReader isntead of an OleDbDataReader, and you could use the methods with any database.
However, the databases have different dialects of SQL, so you either have to stay on a narrow path of features that work in all databases that you use, or have separate queries for some tasks.
A specific example of differences is that Access uses data literals like #2010-09-24# while SQL Server uses date literals like '2010-09-24'. Generally most that has to do with dates differs.
The link you're likely missing is the functionality of the DbProviderFactories class. Using this class (and associated helpers also in System.Data.Common), you can abstract the provider and use references to the base classes (such as DbConnection and DbCommand) to do the work. It'd look something like this:
private void DoSomething(string provider, string connectionString, string something)
{
DbProviderFactory factory = DbProviderFactories.GetFactory(provider);
DbConnection connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
DbCommand command = connection.CreateCommand();
command.CommandText = something;
DbDataReader reader = command.ExecuteReader();
//etc...
}
The provider name is a bit tricky to acquire, but should be the invariant class name that matches one of those returned by DbProviderFactories.GetFactoryClasses(). Or, you can simply hard code them. They don't change much, but it is a magic string embedded in your code and may cause issues eventually.
Additional features can be accessed through factory.CreateCommandBuilder that can help you traverse the differences in how the providers handle things like parameters and such.
I need to set my connection string for Linq to Sql based on an environment variable. I have a function which will return the connection string from the web.config based on the environment variable, but how do I get Linq to always use this "dynamically created" connection string (preferably without having to specify it every time)?
I know I can specify the connection string using the constructor, but how does that work when using the datacontext in a LinqDataSource?
Use:
MyDataClassesDataContext db = new MyDataClassesDataContext(dynamicConnString);
For a LinqDataSource, intercept the ContextCreating event and create the DataContext manually as above:
protected void LinqDataSource_ContextCreating(object sender, LinqDataSourceContextEventArgs e)
{
e.ObjectInstance = new MyDataClassesDataContext (dynamicConnString);
}
From MSDN:
By default, the LinqDataSource control
creates an instance of the type that
is specified in the ContextTypeName
property. The LinqDataSource control
calls the default constructor of the
data context object to create an
instance of the object. It is possible
that you have to use a non-default
constructor or you have to create an
object that differs from the one
specified in the ContextTypeName
property. In that case, you must
handle the ContextCreating event and
manually create the data context
object.
Open up the LINQ to SQL designer, and open the Properties tab of the designer (the schema itself), expand Connection and set Application Settings to False. Save.
Close that down and open up your DataContext designer file (dbml_name.designer.cs) and alter the DataContext constructor. You will immediately notice how your connection string decided to jump in here as you turned off application wide settings. So the part to focus on here is altering the base() inheritor. Renaming ConnString” below to suit your own. I also noticed a DatabaseAttribute on the class which I don’t think plays a big part and has any implications on the connection settings. You will also need a reference to System.Configuration:
public dbDataContext() : base(ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString, mappingSource)
Open the App.config or Web.config featured in the project where your LINQ to SQL classes reside, and rename the connection string to what you defined as “MyConnString“.
You now must Cut the entire entry with name change and Paste it into either the App.config or Web.config of the application which is to access the data, such as a web application, Silverlight, WPF, WCF etc. It is important that you alter the configuration file of the calling application which is to access the data, as the ConfigurationManager defined in your LINQ to SQL classes will look for the .config file from where the calling application is executing from, no matter where your LINQ to SQL classes have been Defined. As you can see, it works a little differently from before.
Now Right Click and open the Properties on your DAL or project containing your LINQ to SQL classes and remove the connection string “Application Setting” reference on the Settings tab.
Rebuild. You’re all done, now just do a Find in Files check for perhaps your database name that you know was featured in the connection string to check for any stragglers, there shouldn’t be any.
The DataContext class has a constructor that takes in a connection string.
you can change the connection string dynamically if you will implement the OnCreated() function. This function is a partial function and it can be implemented in seperate file other than where you dbml exists.
for detail please see this article
http://aspilham.blogspot.com/2011/01/how-do-i-set-connection-string-in-linq.html
When trying to add a few items to the database I'm getting this error:
UpdateException was unhandled by user code
An error occurred while updating the entries. See the InnerException for details.
The InnerException contains this:
{"Column count doesn't match value count at row 1"}
I can't see anything wrong with the objects I'm trying to add, all the required values are filled.
Is there any way of viewing the query that causes the problem?
The method's code, if required:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LaadVerrichtingenIn() {
int[] intArray = Array.ConvertAll<String, int>(Request.Form["selectedObjects"].Split(','), new Converter<String, int>(Convert.ToInt32));
List<Verrichting> gekozenVerrichtingen = new List<Verrichting>();
foreach(int i in intArray){
base._entities.AddToVerrichtingSet(((Dictionary<int, Verrichting>)Session["ingelezenVerrichtingen"])[i]);
gekozenVerrichtingen.Add(((Dictionary<int, Verrichting>)Session["ingelezenVerrichtingen"])[i]);
}
Session["ingelezenVerrichtingen"] = null;
base._entities.SaveChanges(); //Exception occurs here
return View("IngeladenVerrichtingen");
}
base._entities is an ADO.NET Entity Data Model.
Thanks
I'm not sure if there's a 'neater' way to do this with the Entity Framework, but if you're using SQL Server then I'd generally use the SQL Server Profiler to read the queries being executed against the server. If you're using a different database then there may be an equivalent - in any case it would probably be helpful if you let us know.
If you're using MySQL > 5.0.37 it has new query profiler functionality - this should be able to show you the queries being sent.
SQL server profiler will work fine if you're using SQL Server. Within the Entity Framework, you can use the ToTraceString method.
I've just come across the same problem while inserting data using the Entity Framework and MySQL. My hunch is, since I'm using double values, that the decimal separator "," is being misinterpreted as a field separator. I upgraded to Connector version 6.1.0, but still no luck. Maybe this is also going on in your case.
Check out this bug report.
BTW, I found that the following line of code works around the problem:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");