DB LINQ - v0.12 released
This release includes work on stored procs, client-side enums, SQL bulk insert, addition of some ‘101 Linq Samples’, fixes for ‘IS NULL’ clauses.
The project has also been re-licensed under MIT license, to be compatrble with Mono.
November 10th, 2007 at 12:49 pm
I create dynamically extended dblinq entity class at runtime.
public class Klient : EntityBase.xKlient {
public Klient() { }
}
xKLient is generated by DBLinq Postgres sqlmetal:
public partial class xKlient : IModified {
protected bool _isModified_;
public bool IsModified {
get { return _isModified_; }
set { _isModified_ = value; }
}
protected string _p_kood;
…
public xKlient() {
}
public xKlient(string p_kood, string regnr, string vatpayno,
… )
…
From my application I use
db = new mydb(connStr);
var q4 = from k in db.Klients select k;
return q4.ToList();
This causes error
CompileColumnRow: need projData with ctor2
at DBLinq.util.RowEnumeratorCompiler`1.CompileColumnRowDelegate(ProjectionData projData, Int32& fieldID) in C:\dblinq2007\DbLinq\util\RowEnumeratorCompiler.cs:line 121
If I add public contructor containing all properties to Klient class all is OK.
Building full parameter constuctor requires database structure querying or getting properties from xKlient type using reflection.
This makes assembly generation complicated.
How to use Klient class without manually creating contructor containing
all properties ?
November 10th, 2007 at 5:25 pm
Issues which I have found:
A Table bloat
var db = new MyDb(connstring);
causes creation of all objects corresponding to all tables in database.
My database contains 500 tables. Some table creation loads additional assemblies.
Application accesses only few tables at a time.
Creating large number of objects which are not accessed is bad design.
How to force DbLinq to create table objects only when they are first
accessed ?
B. DbLinq.Pgsql.Prototype.dll issues
1. Schema support.
I have multi company PostgreSQL database.
Common data is stored in public schema.
Company data is stored in schemas Company1 , Company2 , …. CompanyN
Every CompanyN schema has exactly the same structure.
Postgres does not searches only from public schema by default so any
reference to other schema fails.
How to force DbLinq or npgsql to invoke command
SET SEARCH_PATH TO public,Company1;
before invoking other commands in every conection ?
If you cannot found better solution can you make the following changes:
1.1. VendorPgSQL.cs and other vendor files:
string settings=”";
///
/// Initialization code ending with semicolon.
/// Example:
/// DBLinq.vendor.Vendor.Settings = “SET SEARCH_PATH TO company1,public;”;
///
// TODO: must be database property generated by pgsqlmetal
public static string Settings {
get { return settings; }
set { settings=value;}
}
1.2. InsertClauseBuilder.cs
change line to
StringBuilder sb = new StringBuilder(Vendor.Settings+”INSERT INTO “);
1.3. RowEnumerator.cs :
protected XSqlCommand ExecuteSqlCommand(XSqlConnection newConn, out DataReader2 rdr2)
{
XSqlCommand cmd = new XSqlCommand(vendor.Vendor.Settings+
_sqlString, newConn);
1.4. There are also other places where
Vendor.Settings()+ should be added.
2. vendor\Pgsql\PgsqlTypeConversions.cs add
case “character”:
return NpgsqlDbType.Char;
3. VendorPgsql.cs is wrong:
public static string FieldName_Safe(string name) {
if (name.ToLower() == “user”)
return “[” + name + “]”;
return name;
}
In Postgres, field names containing reserved words must be in double quotes and are case sensitive when in double quotes.
4. npgsql2 rc1 is now released. DbLinq should use this instead of npgsql 1
5. MONO support. Can somebody provide some sample how to use DBLinq with MONO. MONO Olive contains MS Linq classes.
November 13th, 2007 at 6:18 pm
Andrus, thanks for spotting the bugs and suggesting fixes. Most of your suggestions are now in Subversion, and I am emailing you about the bits I did not understand.
-jiri george
November 18th, 2007 at 6:27 am
I tried to implement dynamic order in DBLinq using the code below with DBLinq rev 78.
I found that simply presence of the statement
Expression> comparer
=Expression.Lambda>( Expression.Property(param,
propertyName), param);
in my code causes exception (shown below) in line
return query.ToList();
This exception means probably that parameters are passed to Klient
constructor in wrong order.
If I simply comment comparer declaration line out, code runs OK.
Any idea how to fix ?
My code:
static public object GetData() {
db = new myDb(connStr);
var query = db.Klients; //.AsQueryable();
string propertyName = “Nimi”;
ParameterExpression param = Expression.Parameter(typeof(Klient), “p”);
// next line presence causes parameters to be passed in wrong order to
// Klient constructor
Expression> comparer=
Expression.Lambda>(
Expression.Property(param, propertyName), param);
return query.ToList();
}
Exception in query.ToList() line:
System.ArgumentException was unhandled
Message=”Expression of type ‘System.String’ cannot be used for constructor
parameter of type ‘System.Decimal’”
Source=”System.Core”
StackTrace:
at System.Linq.Expressions.Expression.ValidateNewArgs(Type type,
ConstructorInfo constructor, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.New(ConstructorInfo
constructor, IEnumerable`1 arguments)
at
DBLinq.util.RowEnumeratorCompiler`1.CompileColumnRowDelegate(ProjectionData
projData, Int32& fieldID) in
C:\dblinqrev78\DbLinq\util\RowEnumeratorCompiler.cs:line 147
at DBLinq.util.RowEnumeratorCompiler`1.CompileRowDelegate(SessionVars
vars, Int32& fieldID) in
C:\dblinqrev78\DbLinq\util\RowEnumeratorCompiler.cs:line 69
at DBLinq.util.RowEnumerator`1.CompileReaderFct() in
C:\dblinqrev78\DbLinq\util\RowEnumerator.cs:line 100
at DBLinq.util.RowEnumerator`1..ctor(SessionVars vars, Dictionary`2
rowCache) in C:\dblinqrev78\DbLinq\util\RowEnumerator.cs:line 92
at DBLinq.Linq.MTable`1.GetEnumerator() in
C:\dblinqrev78\DbLinq\Linq\MTable.cs:line 149
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Business.Business.GetData()
at Program.Main(String[] args) in C:\Documents and
Settings\Administrator\My Documents\Visual Studio
2008\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line
20
..