DataProvider = ProviderFactory.GetProvider("") NullReferenceException? - subsonic

I am getting a NullReferenceException when SubSonic calls the default contructor for my database.
In my case the line it errors on is.
DataProvider = ProviderFactory.GetProvider("MDMA");
I have the namespaces set correctly and the classes seam to be getting generated correctly, so it looks like I can connect to the database. Is this a bug?
I am using version 3.0.0.2.

This line of code requires a connection string in your execution environment with a name "MDMA".

Add a Connection String in the App.Config/Web.Config file with a name "MDMA".
Example:
<add name="MDMA" connectionString="Data Source=[DS];Initial Catalog=[Database];MultipleActiveResultSets=True;User Id=[UID];pwd=[PWD]" providerName="System.Data.SqlClient"/>

Related

How to rewrite the table qualifier at runtime with JOOQ

When generating code using JOOQ for a SQL Server database the generation creates three-part qualifiers like: [catalog].[schema].[table]. This is exactly what I want when working with the SQL Server databases but is an issue when using the generated code with another database like an H2 in memory database for unit testing.
The H2 dialect does not support these three-part qualifiers, H2 expects something like [catalog].[table]. This causes syntax errors when executing commands like the following against H2:
context.createTable(TBLBUSINESSENTITY).columns(TBLBUSINESSENTITY.fields()).execute();
To solve this I need to change the qualifier at runtime which I thought could be done using a render mapping and mapped schema. Unfortunately, this seems to only have the ability to modify the schema portion of the qualifier like this:
Settings settings = new Settings().withRenderMapping(new RenderMapping().withSchemata(
new MappedSchema().withInput("dbo").withOutput("mySchema")));
Given the qualifier [MyDatabase].[dbo].[MyTable], this maps to [MyDatabase].[mySchema].[MyTable] but I cant figure out how to remove that section entirely.
Is there some way to rewrite the mapping to [MyDatabase].[MyTable]?
Use this setting instead:
Settings settings = new Settings()
.withRenderCatalog(false)
.withRenderMapping(new RenderMapping()
.withCatalogs(new MappedCatalog()
.withInput("MyDatabase")
.withSchemata(new MappedSchema()
.withInput("dbo")
.withOutput("MyDatabase"))));

How does Database.SetInitializer actually work? (EF code-first create database and apply migrations using several connection strings)

I am trying to write a method to create a database and run migrations on it, given the connection string.
I need the multiple connections because I record an audit log in a separate database.
I get the connection strings out of app.config using code like
ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
The code works with the first connection string defined in my app.config but not others, which leads me to think that somehow it is getting the connection string from app.config in some manner I don't know.
My code to create the database if it does not exist is
private static Context MyCreateContext(string ConnectionString)
{
// put the connection string where the factory method can get it
AppDomain.CurrentDomain.SetData("ConnectionString", ConnectionString );
var factory = new ContextFactory();
// I know I need this line - but I cant see how what follows actually uses it
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context,DataLayer.Migrations.Configuration>());
var context = factory.Create();
context.Database.CreateIfNotExists();
return context
}
The code in the Migrations.Configuration is
Public sealed class Configuration : DbMigrationsConfiguration<DataLayer.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}
The context factory code is
public class ContextFactory : IDbContextFactory<Context>
{
public Context Create()
{
var s = (string)AppDomain.CurrentDomain.GetData("ConnectionString");
return new Context(s);
}
}
Thus I am setting the connection string before creating the context.
Where can I be going wrong, given that the connection strings are all the same except the database name, and the migration code runs with one connection string, but doesnt run with others?
I wonder if my problem is to do with understanding how How does Database.SetInitializer actually works. I am guessing something about reflection or generics. How do i make the call to SetInitializer tie tie to my actual context?
I have tried the following code but the migrations do not run
private static Context MyCreateContext(string ConnectionString)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, DataLayer.Migrations.Configuration>());
var context = new Context(ConnectionString);
context.Database.CreateIfNotExists();
}
This question appears to be related
UPDATE:
I can get the migrations working if I refer to the connection string using
public MyContext() : base("MyContextConnection") - which points to in the config
I was also able to get migrations working on using different instances of the context, if I created a ContextFactory class and passed the connection to it by referencing a global. ( See my answer to the related question link )
Now I am wondering why it has to be so hard.
I'm not sure exactly as to what the problems are you facing, but let me try
The easiest way to provide connection - and be sure it works that way...
1) Use your 'DbContext' class name - and define a connection in the app.config (or web.config). That's easiest, you should have a connection there that matches your context class name,
2) If you put it into the DbContext via constructor - then be consistent and use that one. I'd also suggest to 'read' from config connections - and again name it 'the same' as your context class (use the connection 'name', not the actual string),
3) if none is present - EF/CF makes the 'default' one - based on your provider - and your context's class name - which usually isn't what you want,
You shouldn't customize with initializers for that reason -
initializers should be agnostic and serve other purpose - setup
connection in the .config - or directly on your DbContext
Also check this Entity Framework Code First - How do I tell my app to NOW use the production database once development is complete instead of creating a local db?
Always check 'where your data' goes - before doing anything.
For how the initializer actually works - check this other post of mine, I made a thorough example
How to create initializer to create and migrate mysql database?
Notes: (from the comments)
Connection shouldn't be very dynamic - config is the right place for it to be, unless you have a good reason.
Constructor should work fine too.
CreateDbIfNotExists doesn't work well together with the 'migration' initializer. You can just use the MigrateDatabaseToLatestVersion initializer. Don't 'mix' it
Or - put something like public MyContext() : base("MyContextConnection") - which points to <connectionStrings> in the config
To point to connection - just use its 'name' and put that into constructor.
Or use somehting like ConfigurationManager.ConnectionStrings["CommentsContext"].ConnectionString
Regarding entertaining 'multiple databases' with migrations (local and remote from one app) - not exactly related - but this link - Migration not working as I wish... Asp.net EntityFramework
Update:
(further discussion here - Is adding a class that inherits from something a violation of the solid principles if it changes the behavior of code?)
It is getting interesting here. I did manage to reproduce the problems you're facing actually. Here is a short breakdown on what I think it's happening:
First, this worked 'happily':
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<MyContext, MyProject.Migrations.Configuration>());
for (var flip = false; true; flip = !flip)
{
using (var db = new MyContext(flip ? "Name=MyContext" : "Name=OtherContext"))
{
// insert some records...
db.SaveChanges();
}
}
(I used custom initializer from my other post, which controls migration/creation 'manually')
That worked fine w/o an Initializer. Once I switched that on, I ran into some curious problems.
I deleted Db-s (two, for each connection). I expected to either not work, or create one db, then another in the next pass (like it did, w/o migrations, just 'Create' initializer).
What happened, to my surprise - is it actually created both databases on the first
pass ??
Then, being a curious person:), I put breakpoints on the MyContext ctor, and debugged through the migrator/initializer. Again empty/no db-s etc.
It created first instance on my call within the flip. Then on the first access to 'model', it invoked the initializer. Migrator took over (having had no db-s). During the migrator.Update(); it actually constructs the MyContext (I'm guessing via generic param in Configuration) - and calls the 'default' empty ctor. That had the 'other connection/name' by default - and creates the other Db all as well.
So, I think this explains what you're experiencing. And why you had to create the 'Factory' to support the Context creation. That seems to be the only way. And setting some 'AppDomain' wide 'connection string' (which you did well actually) which isn't 'overriden' by default ctor call.
Solution that I see is - you just need to run everything through factory - and 'flip' connections in there (no need for static connection, as long as your factory is a singleton.
You can supply a configuration in the MigrateDatabaseToLatestVersion constructor.
If you set the initializer in the DbContext you can also pass a 'true' to use the current connection string.

Entity Framework my DB Context does not have connection when Reference in other Project

So here is my problem Guys
In my Solution,
I have ORM Class Liberary where I've added EntityFramework 5 (so has .edmx containing Context.tt
Designer.cs, edmx.diagram and .tt) files.. So far so good
And I have Project called Repositories and has reference of ORM project above.
In HeaderRepository class of Repositories Project, when I write following code,
using(UFPEntities ufpEntities = new UFPEntities())
{
try{
Header header = ufpEntities.Headers.Single(x => x.VendorId == id);
}catche(Exception e)
{
}
}
Note: intellisense works fine COMPILER DOES NOT GIVE ERROR while writing above code, it happens at Run time
But, I get "No connection string named 'UFPEntities' could be found in the application config file."
App.config is in ORM Project, not in Repository Project where I am dealing with Data as Above.
Can you please help me so that I can CREATE MY MODEL class (such as Header) from Repository Project? or What I am doing wrong so it gives me Exceptions?
Thx in Advance.
The connection string must be in config of entry assembly - it is either web.config for web application or app.config for executable or unit test library. App.config for arbitrary library which is just referenced by executed code is completely ignored.

Bean Autowiring problem

I am starter in mutithreading. I am trying to index my data into solr.For that I was writing the following code
I am getting null pointer exception in the line highlighted
You need to add the following:
<context:annotation-config/>
You need to set the path for autowiring package scan and in your case it will be:
<context:component-scan base-package="a.b.c" />
After it you need to mark the class as candidate for autowiring:
#Component("indexTask")
#Scope("prototype")
IndexTask implements Callable<IndexObject>
{
//ommited
}
Next you can remove indexTask bean configuration from xml file. your package will be created automatically.
Hope it helps.
Autowiring doesn't happen automatically, you need to configure it. See the Spring docs for detail, but essentially you need to add
<context:annotation-config/>

Problem with RunMigrations in SimpleRepository Example - Subsonic 3

I downloaded today Subsonic 3 and tried out the examples. I am having a problem with the SimpleRepository example and I wondered if anyone else has had this. In the HomeController there is a defintion as follows:
public HomeController() {
_repo = new SimpleRepository("Blog");
}
I wanted to enable the migrations and so changed it to this:
public HomeController() {
_repo = new SimpleRepository("Blog", SimpleRepositoryOptions.RunMigrations);
}
However, when this runs it causes an error - stating an issue "String or binary data would be truncated.".
If it makes a difference, the version of VS is 2008 (with the GDR applied)
This is still an issue in the latest 3.0.0.1 and .2 downloads..
You get this error message if the migration you are trying to run would edit/truncate data in your database.
Do you have sql profiler available? That way you can see the sql statement. If you don't have sql profiler available you will need to download the source and use debug to see the actual sql statement that it is trying to execute.
Way way way late to this party, but you probably need to add the [SubSonicLongString] attribute to the columns that have more than the default 225 characters for a plain String.

Resources