DataContext constructor

268 views
Skip to first unread message

bryan costanich

unread,
Oct 4, 2008, 6:04:52 PM10/4/08
to DbLinq
Hi all,

In working with the generated c# LINQ classes from DBMetal, i've
noticed that the two DataContext constructors both require an
IDbConnection, whereas the .net ones also allow you to pass among
other things, just a connection string.

Looking into it, i see that the underlying DBLinq.DataContext class
actually has the constructors there, but they're unimplemented. they
are a little different though. they expect a
"fileOrServerOrConnection" string. but i'm not sure even what that
means.

I think this should be added for a couple reasons. 1) to preserve
fidelity with the .net implementation, and 2) it's really damn useful.

in thinking about maybe adding this, some questions popped up, namely:
-> what is the intent here, i believe the .net version supports only
valid db connection strings
-> if we get something in here, how do we determine the correct way to
initialize the connection, e.g. do we parse the 'provider'? what if
there is none? is there a standard here we should be looking at, e.g.
only valid .net connection strings?

for now, personally, all i care about is mySQL, so i'm happy to throw
something in there that parses a valid .net connection string and if
the provider is DBLinq.MySql (or whatever it should be called), then
create a MySQL Connection, otherwise it would just throw an exception
- would that piss anyone off?

perhaps i'm not the best person to be doing this, since i'm not
intimately familiar with the project, so if someone else wants to,
that would be even better, but i would like to use it soon.

thoughts?

-b

Pascal Craponne

unread,
Oct 5, 2008, 3:58:54 PM10/5/08
to dbl...@googlegroups.com
Hi Bryan,

Passing only a connection string means that we will create an IDbConnection implementation from this connection string. This means that something somewhere in DbLinq needs to reference the ADO.NET driver.
...And this is the first thing I removed when I entered the project, because we can not glue DbLinq to any version of any ADO driver.
The best sample is for Oracle drivers, where you can use Microsof's driver or Oracle's ODP driver. Since also Oracle's ODP drivers still coexist in different versions, each being related to an Oracle database version, you can easily understand that sticking to a specific ADO.NET provider is bab.

I think we could find a trick, but I have no idea yet (maybe hardcore reflexion, like enumerating all loading IDbConnection implementations loaded in current AppDomain).

Do you have a better idea? This would also help Mono to implement multi-database support.

Pascal.

--
Pascal.

jabber/gtalk: pas...@jabber.fr
msn: pas...@craponne.org

Atsushi Eno

unread,
Oct 6, 2008, 1:42:31 PM10/6/08
to dbl...@googlegroups.com
Hi,

To my understanding, an essential problem with related to this
fileOrServerOrConnection is that it could be either a filename,
server name or a connection string. Hence, this string is not
always valid connectionString for SqlConnection.
And not all database engines support constructing database
connection by a filename (even SQL Server 2000 does not).

(And as Pascal explained, this connection string has to identify
the target DBMS.)

To implement support for this mere string, those complexities
has to be solved.

Atsushi Eno

Pascal Craponne

unread,
Oct 6, 2008, 6:28:29 PM10/6/08
to dbl...@googlegroups.com
Today, I can find only one way to identify a database given a single connection string: testing it using different drivers. And this sucks.

We could implement a less-sucking method, with a two steps process:
1. for each vendor, say if yes or no it could handle the given connection string as a valid one
2. for all vendors who answered yes, test them, by trying to connect them.

And this leads to the second problem, which is creating a an IDbConnection from a given string, this IDbConnection being compatible with the tested vendor.

Maybe another approach would be to "brute force test" all drivers (IDbConnection) present in current AppDomain, and once found the correct one, find the Vendor that could handle it. This second approach would also solve the case where we only give the IDbConnection instance.

Anyway, I don't really like those solutions. This is a dirty hack.

A better idea, someone?

Andrus

unread,
Oct 7, 2008, 4:13:10 AM10/7/08
to dbl...@googlegroups.com

> A better idea, someone?

In entity framework you need to add an entry to machine.config in the
<DbProviderFactories> section.

For PostgreSQL It should look like this:

<add name="Npgsql Data Provider" invariant="Npgsql" description=".Net
Framework Data Provider for PostgreSQL Server" type="Npgsql.NpgsqlFactory,
Npgsql,
Version=1.99.2.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"/>

Sample edmgen (dbmetal/sqlmetal analoque) to generate the model files:

edmgen.exe /provider:Npgsql /mode:fullgeneration
/connectionstring:"postgresql
connection string" /project:ProjectNamespace

Maybe it is possible to use ADO .NET dataprovider factory as shown above.

Andrus.

Pascal Craponne

unread,
Oct 7, 2008, 4:49:52 AM10/7/08
to dbl...@googlegroups.com
This is not a tool problem, this is an API problem:

If I want to create a DataContext given a connection string (the worst case), how do I know, when I type
"new DataContext("database=mydb")"
which DbLinq vendor should be used internally (I assume several vendors are already registered, which is not a problem).

Even my solution (exposed a few messages ago), can not solve it in an unique way. What if two vendors can handle a given connection string?

Andrus

unread,
Oct 7, 2008, 5:06:25 AM10/7/08
to dbl...@googlegroups.com
 
If I want to create a DataContext given a connection string (the worst case), how do I know, when I type
"new DataContext("database=mydb")"
which DbLinq vendor should be used internally (I assume several vendors are already registered, which is not a problem).

Even my solution (exposed a few messages ago), can not solve it in an unique way. What if two vendors can handle a given connection string?
Require adding "provider=npgsql;" to start of connection string
 
"new DataContext("provider=npgsql;database=mydb")"
 
and remove this addition when passing conn string to connection creator?
 
ODBC drivers probably use this method, ODBC driver manager removes special tokens.
 
Andrus.

Atsushi Eno

unread,
Oct 7, 2008, 5:07:55 AM10/7/08
to dbl...@googlegroups.com
In such cases, simply the defined order in the DBProviderFactories
configuration could take effect.

Or define custom configuration sections for DBLinq itself to determine
preferred vendor types in order.

An alternative solution is to create a static class to define
the preferred order of vendors (something like
DBLinqConfiguration.PreferredVendors). It could be combined
with configuration settings, and it won't suck for those who
don't like configuration settings.

Though I have to say I do not love my idea. It is sort of hack ;)

Atsushi Eno

Pascal Craponne wrote:
> This is not a tool problem, this is an API problem:
>
> If I want to create a DataContext given a connection string (the worst
> case), how do I know, when I type
> "new DataContext("database=mydb")"
> which DbLinq vendor should be used internally (I assume several vendors
> are already registered, which is not a problem).
>
> Even my solution (exposed a few messages ago), can not solve it in an
> unique way. What if two vendors can handle a given connection string?
>
> On Tue, Oct 7, 2008 at 10:13, Andrus <kobru...@hot.ee
> <mailto:kobru...@hot.ee>> wrote:
>
>
>
> > A better idea, someone?
>
> In entity framework you need to add an entry to machine.config in the
> <DbProviderFactories> section.
>
> For PostgreSQL It should look like this:
>
> <add name="Npgsql Data Provider" invariant="Npgsql"
> description=".Net
> Framework Data Provider for PostgreSQL Server"
> type="Npgsql.NpgsqlFactory,
> Npgsql,

> Version=1.99.2.0 <http://1.99.2.0>, Culture=neutral,


> PublicKeyToken=5d8b90d52f46fda7"/>
>
> Sample edmgen (dbmetal/sqlmetal analoque) to generate the model files:
>
> edmgen.exe /provider:Npgsql /mode:fullgeneration
> /connectionstring:"postgresql
> connection string" /project:ProjectNamespace
>
> Maybe it is possible to use ADO .NET dataprovider factory as shown
> above.
>
> Andrus.
>
>
>
>
>
>
> --
> Pascal.
>

> jabber/gtalk: pas...@jabber.fr <mailto:pas...@jabber.fr>
> msn: pas...@craponne.org <mailto:pas...@craponne.org>
>
>
> >

Pascal Craponne

unread,
Oct 7, 2008, 5:43:08 AM10/7/08
to dbl...@googlegroups.com
So, here are the options:
1. We can use an additional identifier in the connection string (I love this idea). Can this work with Mono requirements?
2. Otherwise we can try to identify the suitable vendor, by:
   a. Identifying for each vendor if it can handle the provided connection string
   b. Trying to use it
   c. All of this in a preferred order (at least, this solves the randomness, so it's not that bad ;))

Does everyone find his ideas here?

Atsushi Eno

unread,
Oct 7, 2008, 8:53:43 AM10/7/08
to dbl...@googlegroups.com
Hola,

Pascal Craponne wrote:
> So, here are the options:
> 1. We can use an additional identifier in the connection string (I love
> this idea). Can this work with Mono requirements?

Yes. I love the idea too :)

Atsushi Eno

bryan costanich

unread,
Dec 1, 2008, 7:26:06 PM12/1/08
to DbLinq
I second that.

the other ones are either too slow, too hacky, or just plain brittle.

what's the status on this? has anyone tried implementing it?

bryan costanich

unread,
Dec 1, 2008, 7:32:59 PM12/1/08
to DbLinq
nevermind, i found a thread on it.
-b
Reply all
Reply to author
Forward
0 new messages