I am making an attempt to establish a connection to a MySQL server using BLToolkit, and have installed MySql.Data (6.5.4), BLToolkit (4.1.12) and BLToolkit.MySql (4.1.12) via NuGet. I can make a connection to a MSSQL server in a single line, but have had trouble with MySQL and ended up with the following configuration file ...
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<BLToolkit>
<dataProviders>
<add type="BLToolkit.Data.DataProvider.MySqlDataProvider" />
</dataProviders>
</BLToolkit>
<configSections>
<section name="BLToolkit" type="BLToolkit.Configuration.BLToolkitSection, BLToolkit.4" />
</configSections>
<connectionStrings>
<add name="Test"
connectionString="Data Source=localhost;Port=3306;Database=bltest;User ID=root;Password=root;"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
</configuration>
I have extended the DbManager class to implement a reference to the tables, and passed the name of the connection string into the base class. This is how I implemented this behaviour, which should be telling BLToolkit to load the connectionString from the configuration file ...
class BlDb : DbManager {
public BlDb()
: base("Test") {
return;
}
public Table<Car> Car { get { return GetTable<Car>(); } }
public Table<Make> Make { get { return GetTable<Make>(); } }
}
An exception, however, is thrown. The exception is "The type initializer for 'BLToolkit.Data.DbManager' threw an exception." with the inner exception being "Configuration system failed to initialize". How should I proceed? Please note that a similar question does exist on SO, Getting BLToolkit to work with MySQL, which might be a helpful reference for you but doesn't make any sense whatsoever to me. Is installing both NuGet packages not enough?
Firts you need to add the reference to the BLToolkit.Data.DataProvider.MySql.4.dll to your project. Then modify your extended DbManager class to look as the following
class BlDb : DbManager
{
public BlDb()
: base( new BLToolkit.Data.DataProvider.MySqlDataProvider(), "Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword" )
{
}
public Table<Car> Car { get { return GetTable<Car>(); } }
public Table<Make> Make { get { return GetTable<Make>(); } }
}
you can replace the hard-coded connection string and return it from your app.config file like ConfigurationManager.ConnectionStrings["Test"].ConnectionString
Related
I'm trying to run integration tests for my ASP.NET MVC application using Entity Framework 6.
The error I get is
System.Data.Entity.Core.EntityException: The underlying provider failed on Rollback. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: connection
The code looks like this:
Database.SetInitializer(new PrimaryInitializerTest());
_context = new PrimaryContextTest();
_context.Database.Initialize(true);
using (var dbt = _context.Database.BeginTransaction())
{
dbt.Commit();
dbt.Rollback();
}
I also tried having an dbt.UnderlyingTransaction.Connection.Open() call just below the using statement, and a dbt.UnderlyingTransaction.Connection.Close() call just below the call to Rollback(). That gave me the error Connection is not closed.
PrimaryInitializerTest class
protected override void Seed(PrimaryContextTest context)
{
// (...) Input some values
base.Seed(context);
}
PrimaryContextTest class
public class PrimaryContextTest : DbContext
{
public PrimaryContextTest() : base("PrimaryContextTest")
{
Database.SetInitializer(new DropCreateDatabaseAlways<PrimaryContextTest>());
}
public DbSet<Story> Stories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
}
Connection string
<add name="PrimaryContextTest"
connectionString="Data Source=(LocalDb)\mssqllocaldb;Initial Catalog=PrimaryContextTest;Integrated Security=SSPI;AttachDbFilename=|DataDirectory|\PrimaryContextTest.mdf"
providerName="System.Data.SqlClient" />
Context string
<context type="fcon.DAL.Tests.PrimaryContextTest, fcon, Version=1.0.0.0, Culture=neutral">
<databaseInitializer type="fcon.DAL.Tests.PrimaryInitializerTest, fcon" />
</context>
What could I be doing wrong?
Might mention that the database doesn't exist in the App_Data folder...
You're calling Commit and then Rollback, but the comments point that mistake out.
The error isn't very intuitive, I mean, an ArgumentNullException should never work its way out of an SDK from down the stack.
But I've had this when I've accidentally reused the same transaction instance, or called Commit twice, or tried to rollback twice in layered error recovery logic.
I am admittedly going a little bit crazy on the subject, so bear with me. I've been attempting to do this for about 5 hours now, and I'm pretty much just banging my head against the wall at this point. Here is what I have:
Global.asax.cs
namespace MyApp
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Database.SetInitializer(new MyInitializer());
}
}
}
MyInitializer.cs
namespace MyApp.App_Start
{
public class MyInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
protected override void Seed(MyContext context)
{
// seed data goes here
sample_data = new List<MyModel>
{
new MyModel{"foo"},
new MyModel{"bar"}
};
sample_data.ForEach(s => context.MyModels.Add(s));
context.SaveChanges();
}
}
}
MyContext.cs
namespace MyApp.Models
{
public class MyContext : DbContext
{
public MyContext() : base("MyContext")
{
Database.SetInitializer<MyContext>(new MyInitializer());
}
public DbSet<MyModel> MyModels { get; set; }
}
}
Web.config
<connectionStrings>
<add name="MyContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=MyContext; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|MyContext.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<contexts>
<context type="MyApp.Models.MyContext, MyApp">
<databaseInitializer type="MyApp.App_Start.MyInitializer, MyApp" />
</context>
</contexts>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
I just cannot figure out why it's not seeding any of the data. I've read through the dozen or more similar cases here and elsewhere, tried just about every iteration, and still can't get it to trigger at all. It never even hits the Seed() function. The database exists, and if I remove it, it is rebuilt, but never populated.
I'm leaning towards there being a problem with my web.config, but I haven't figured it out yet. Any suggestions?
According to this blog, the DbInitializer isn't called until you actually try to access the database.
// Code copied from linked blog
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<BlogContext>());
using (var db = new BlogContext()) //initializer won't be called here
{
...
db.Categories.Add(cat); //initializer will be called here
db.BlogPosts.Add(post);
...
}
Console.ReadLine();
}
I resolved this. Apparently, the issue was two-fold.
The "DropCreateDatabaseIfModelChanges" in the initializer wasn't firing, as it didn't see that the model had changed. Changing this to "DropCreateDatabaseAlways" worked, but would usually result in a "Cannot drop database because it is currently in use" error message. A manual disconnect of databases and restart of VS usually resolved this, though I still usually had to run it 2-3 times. Once it dropped and rebuilt the database, reverting to "DropCreateDatabaseIfModelChanges" is faster and still works.
I may have been missing a line in my Web.config
<appSettings>
<add key="MyInitializer MyApp.Models.MyContext, MyApp.Models" value="MyApp.App_Start.MyInitializer, MyApp.Models" />
</appSettings>
Between these two things [well, more like 4 things], it seems to work now.
For some context, I want to open a connection to a database and execute some queries.
Here's my App.config:
<dbservers>
<connectionStrings>
<add name="Cube_ConnectionString" connectionString="OLEDB; Datasource=http://cube.com; Initial Catalog=BP" />
</connectionStrings>
<queries>
<add connectionStringName="CubeConnectionString" usedBy="DataAccessor" connectionString="" />
</queries>
</dbservers>
This is how I intend to retrieve the connectionString:
System.Configuration.ConfigurationManager.ConnectionStrings["Cube_ConnectionString"].ConnectionString;
I am wondering whether GetSection or ConnectionString would be best to use. And what would be returned for both of them? How do these two methods function within nested XML such as this?
Additionally, what's the purpose of putting queries in the app.config?
Thanks in advance
I don't think that ConnectionStrings will work unless you put them in the standard section for those. If you want a custom <dbservers> section, you'll have to use GetSection instead.
This functionality is a bit awkward, but highly useful. How to: Create Custom Configuration Sections Using ConfigurationSection is a useful guide for this.
Essentially this boils down to creating a class that inherits from ConfigurationSection, and adding the proper attributes (from the above guide):
public class PageAppearanceSection : ConfigurationSection
{
// Create a "remoteOnly" attribute.
[ConfigurationProperty("remoteOnly", DefaultValue = "false", IsRequired = false)]
public Boolean RemoteOnly
{
get
{
return (Boolean)this["remoteOnly"];
}
set
{
this["remoteOnly"] = value;
}
}
// Create a "font" element.
[ConfigurationProperty("font")]
public FontElement Font
{
get
{
return (FontElement)this["font"]; }
set
{ this["font"] = value; }
}
// Create a "color element."
[ConfigurationProperty("color")]
public ColorElement Color
{
get
{
return (ColorElement)this["color"];
}
set
{ this["color"] = value; }
}
}
...and then adding a reference to your section in the app/web.config:
<configuration>
<configSections>
<section name="dbservers" type="Namespace.DbServersSection, YourAssembly"/>
</configSections>
</configuration>
i am trying to get connection string from method resulting error object reference not set to the instance object my method is,
this method return connection,
namespace InspectionServices.Services
{
public class ConfigManager
{
public static string GetConnectionString()
{
return ConfigurationManager.ConnectionStrings["***"].ConnectionString;
}
}
}
and here i am getting connection by calling method mentioned above,
string connectionString = InspectionServices.Services.ConfigManager.GetConnectionString();
hopes for your suggestion
Thanks in Advance
EDITED:
Appconfig,
<connectionStrings>
<add name="Inspection" connectionString="Data Source=***;Database=***;Integrated Security=SSPI; Persist Security Info=false; Trusted_Connection=Yes;" providerName="System.Data.SqlClient"/>
</connectionStrings>
You mush have web.config entries like this
<connectionStrings>
<add name="name" connectionString="***" />
</connectionStrings>
Only then you can use it in your class.
Some useful links
C# Configuration Manager . ConnectionStrings
http://www.connectionstrings.com/Articles/Show/store-connection-string-in-web-config
namespace InspectionServices.Services
{
public class ConfigManager
{
public static string GetConnectionString()
{
return ConfigurationManager.ConnectionStrings["Inspection"].ConnectionString;
}
}
}
I'm currently trying to use the same DbContext (I have two databases, of identical structure) in my application. I'm not quite sure what I'm doing wrong, but here's my current code - hopefully it should be pretty obvious what I'm trying to do. I'm using EF Database First (which the error at the bottom seems not to suggest).
My context factory code:
public class HOLContextFactory
{
public static HOLDbEntities Create()
{
return new HOLDbEntities(); // Works
}
public static HOLDbQuoteEntities CreateQuote()
{
return new HOLDbQuoteEntities(); // Gives error
}
}
public partial class HOLDbQuoteEntities : HOLDbEntities
{
public HOLDbQuoteEntities()
: base("HOLDbQuoteEntities") // This should send "HOLDbQuoteEntities" as the base connection string?!
// Also tried "name=HOLDbQuoteEntities"
{
}
}
Web.config connection strings:
<add name="HOLDbEntities" connectionString="metadata=res://*/HOLDbContext.csdl|res://*/HOLDbContext.ssdl|res://*/HOLDbContext.msl;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />
<add name="HOLDbQuoteEntities" connectionString="metadata=res://*/HOLDbContext.csdl|res://*/HOLDbContext.ssdl|res://*/HOLDbContext.msl;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" /> // using diff database - same structure
Error I'm getting when using "HOLDbQuoteEntities" :
Code generated using the T4 templates for Database First and Model
First development may not work correctly if used in Code First mode.
To continue using Database First or Model First ensure that the Entity
Framework connection string is specified in the config file of
executing application. To use these classes, that were generated from
Database First or Model First, with Code First add any additional
configuration using attributes or the DbModelBuilder API and then
remove the code that throws this exception**
Entity Framework needs to use the actual entities object:
public class HOLContextFactory
{
public static HOLDbEntities Create()
{
// default connection string
return new HOLDbEntities();
}
public static HOLDbEntities CreateQuote()
{
// specified connection string
return new HOLDbEntities ("HOLDbQuoteEntities");
}
}
public partial class HOLDbEntities
{
public HOLDbEntities(string connectionString)
: base(connectionString)
{
}
}
}
I've done the same thing in one of my project. I am creating my entity context using metadata=res://*/
Try this:
<add name="HOLDbEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />
<add name="HOLDbQuoteEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />