Object definition of standard way - Google Project Hosting

perchmysteriousData Management

Dec 1, 2012 (4 years and 9 months ago)

294 views

I.

Getting started


1.

The first sight

䉡s楣⁵ 慧e


2.

First application
:
The following steps shows how to create a basic
database application using DbEntry.Net:



Create a console application using Visual Studio 2008
.



Create a new Access mdb file named
test.mdb
, and store it to
c:
\
. If you are using
Access 2007, please save it as Access 2003 format.



Add the reference of
Lephone.Data.dll
and
Lephone.Util.dll
to this application.



Add an
App.config
to this applicatio
n.



Open it in vs2005, and change it as following:



<?
xml

version
=
"
1.0
"
encoding
=
"
utf
-
8
"
?>

<
configuration
>


<
configSections
>


<
section

name
=
"
Lephone.Settings
"


type
=
"
Lephone.Util.Setting.NameValueSectionHandler, Lephone.Util
"
/>


</
configSections
>




<
Lephone.Settings
>


<
add

key
=
"
AutoCreateTable
"
value
=
"
true
"
/>


<
add

key
=
"
DataBase
"
value
=
"
@Access : @C:
\
test.mdb
"
/>


</
Lephone.Settings
>

</
configuration
>

(
If you are using Vista, please choose other drive like D:

)


Add a class file named
User.cs
to this application.


Open it in vs2005, and change it as following:

using

Lephone.Data.Definition;



public

class

User : DbObject

{


public

string

Name;

}


Open
Program.cs
and change it as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main(
string
[] args)


{


User u =
new

User();


u.Name =
"tom"
;


Console.WriteLine(
"New object:
\
n{0}"
, u);


DbEntry.Save(u);


Console.WriteLine(
"Saved object:
\
n{0}"
, u);



Console.ReadLine();


}

}


Run this application, it will shows:

New object:

{ Id = 0, Name = tom }

Saved object:

{ Id = 1, Name = tom }



Check the
c:
\
test.mdb
file, confirm the
User
table already created and it has one row data, check the data
of this row, confirm the
Name
column is
tom
:

Id

Name

1

tom


Re
-
run this application, it will shows:

New object:

{ Id = 0, Name = tom }

Saved object:

{ Id = 2, Name = tom }



Check the
c:
\
test.mdb
file, confirm the data of
User
table is following:

Id

Name

1

tom

2

tom


3.

Basic CRUD
:

In
First application
, it shows how to insert a new object to database:


User u =
new

User();


u.Name =
"tom"
;


DbEntry.Save(u);

Now, let's
continue this work to change this code to complete basic CRUD for
database.


First, make sure the
c:
\
test.mdb

has
User

table, and the table data is following:

Id

Name

1

tom

2

tom


Open
Program.cs

and change it as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main(
string
[] args)


{


User u = DbEntry.GetObject<User>(1);


Console.WriteLine(u);


Console.ReadLine();


}

}


Run this application, it will shows:

{ Id = 1, Name = tom }


Edit the
Program.cs
as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main(
string
[] args)


{


User u = DbEntry.GetObject<User>(1);


Console.WriteLine(
"Read Object:
\
n{0}"
, u);


u.Name =
"jerry"
;


DbEntry
.Save(u);


User u1 = DbEntry.GetObject<User>(1);


Console.WriteLine(
"Updated Object:
\
n{0}"
, u1);


Console.ReadLine();


}

}


Run this application, it will shows:

Read Object:

{ Id = 1, Name = tom }

Updated Object:

{ Id

= 1, Name = jerry }


Edit the
Program.cs

as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main(
string
[] args)


{


User u = DbEntry.GetObject<User>(2);


Console.WriteLine(
"Read Object:
\
n{0}"
, u);


DbEntry.Delete(u);


User u1 = DbEntry.GetObject<User>(2);


if

(u1 ==
null
)


{


Console.WriteLine(
"After delete, the object doesn't find."
);


}


Console.ReadLine();


}

}


Run this application, it will shows:

R
ead Object:

{ Id = 2, Name = tom }

After delete, the object doesn't find.


Open the
c:
\
test.mdb

file, confirm the
User

table is following:

Id

Name

1

jerry


Ok, we just finished the basic CRUD, have fun!


4.

Enter dynamic
:

After we finished
Basic CRUD
, let's continue enter
the world of dynamic object.




First, create a new
c:
\
test.mdb

file.



Open
User.cs

and change it as following:

using

Lephone.Data.Definition;



public

abstract

class

User : DbObjectModel<User>

{


public

abstract

string

Name {
get
;
set
; }


public

abstract

User Init(
string

Name);

}


Open
Program.cs

and change it as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main()


{


// Insert


User.New.Init(
"jerry"
).Save();


User u = User.New.Init(
"mike"
);


u.Save();


Console.WriteLine(
"Insert :
\
n{0}
\
n"
, u);


// Select


User u1 = User.FindById(
u.Id);


Console.WriteLine(
"Select :
\
n{0}
\
n"
, u1);


// Update


u1.Name =
"tom"
;


u1.Save();


Console.WriteLine(
"Update :
\
n{0}
\
n"
, u1);


// Select All


ShowAll(
"Select all :"
);


// Delete


u1.Del
ete();


ShowAll(
"After delete :"
);



Console.ReadLine();


}




static

void

ShowAll(
string

msg)


{


Console.WriteLine(msg);


foreach
(User o
in

User.FindAll(
new

OrderBy(
"Id"
)))


{


Console.WriteLine(o);


}


Console.WriteLine();


}

}


Run this application, it will shows:

Insert :

{ Id = 2, Name = mike }


Select :

{ Id = 2, Name = mike }


Update :

{ Id = 2, Name = tom }


Select all :

{ Id = 1, Name = jerry }

{ Id = 2, Name = tom }


After
delete :

{ Id = 1, Name = jerry }


Open the
c:
\
test.mdb

file, confirm the
User

table is following:

Id

Name

1

jerry

5.

Transaction
:
After we finished
Enter dynamic
, let's continue to
learn how to using transaction.



First, create a new
c:
\
test.mdb

file.



Open
Program.cs

and change it as following:

using

System;

using

Lephone.Data;



class

Program

{


static

void

Main()


{


// Insert


User.New.Init(
"tom"
).Save();


ShowAll(
"Insert tom :"
);


DbEntry.UsingTransaction(
delegate


{


User.New.Init(
"jerry"
).Save();


User.New.Init(
"mike"
).Save();


});


ShowAll(
"Insert jerry and mike :"
);


// Insert and excepton


try


{


DbEntry.UsingTransaction(
delegate


{


User.New.Init(
"rose"
).Save();


User.New.Init(
"bill"
).Save();


int

n = 0;


n = 5 /
n;
// emu exception


});


}


catch

{}


ShowAll(
"Inserted rose and bill, but has exception :"
);




Console.ReadLine();


}




static

void

ShowAll(
string

msg)


{


Console.WriteLine(msg);


foreach
(
User o
in

User.FindAll(
new

OrderBy(
"Id"
)))


{


Console.WriteLine(o);


}


Console.WriteLine();


}

}


Run this application, it will shows:

Insert tom :

{ Id = 1, Name = tom }


Insert jerry and mike :

{ Id = 1, Name = tom }

{

Id = 2, Name = jerry }

{ Id = 3, Name = mike }


Inserted rose and bill, but has exception :

{ Id = 1, Name = tom }

{ Id = 2, Name = jerry }

{ Id = 3, Name = mike }


Open the
c:
\
test.mdb

file, confirm the
User

table is following:

Id

Name

1

tom

2

jerry

3

mike



II.

Definition and Configuration:


1.

O
bject definition

Ob橥捴⁤敦楮et楯渠n映fta湤慲搠睡w:


public

abstract

class

User : DbObjectModel<User>

{


public

abstract

string

Name {
get
;
set
; }

}

This will create an object model, and the object has some functions like
Save
,
Delete
, it also has some static
functions like
New
,
Find
,
FindById
,
FindBySql

etc.


Attention for this mode, the generic argument of
DbObjectModel

must same as defined class,

otherwise it will
cause something we do not expected.


If an object inherits from
DbObjectModel

and using abstract properties, it provide partial update for the object,
in partial update mode, in
Update

function, it only update the columns which is change
d, it doesn't call
database if nothing changed.
DbObjectModel

is inherits from
DbObject
.
(In fact, there is another class
DbObjectSmartUpdate between them, but it not the recommanded class to inherits from.)

User u = User.New;

u.Name =
"tom"
;

u.Save();

Use
r u1 = User.FindById(u.Id);

Also we can create an object inherits from
DbObject
, and doesn't use abstract style:

public

class

User : DbObject

{


public

string

Name;

}

In this way, it doesn't has extra functions in it,
DbObject

only provide an primary ke
y column named "Id", so it
means in this object it has two columns:
Name

and
Id
, the
Id

column type is long, and it's aoto increments
primary key of this table.


It should using
DbEntry

to operate it:

User u =
new

User();

u.Name =
"tom"
;

DbEntry.Save(u);

User u1 = DbEntry.GetObject<User>(u.Id);

Also we can create an object inherits from
System.Object
:

public

class

User : IDbObject

{


public

string

Name;

}

In this way, it only have one column named "Name", nothing extra. This type of objects can operate
like other
objects inherits from
DbObject
, only it don't has the primary key "Id", but you can defined another primary key
or mutil
-
key for it.


For example, if we want the
Name

column is the primary key of this table, we just need change the object model
as following:

public

class

User : IDbObject

{


[DbKey(IsDbGenerate=
false
), Length(50)]


public

string

Name;

}

It is almost like the other base class
NamedDbObject
, so if we want using string type
Name

column as primary
key, we can inherits from
Named
DbObject
, the little different is the max length of
Name

column is 255 in
NamedDbObject
:

public

class

User : NamedDbObject, IDbObject

{

}

But in this case, because the object is not have a system generated primary key, so the
Save

function does not
works,
we should use
Insert

or
Update

function by ourself.


If we want to define the auto increments primary key as another name, we can difine it as following:

public

class

User : IDbObject

{


[DbKey]


public

long

userID;




public

string

Name;

}

The
UnsavedValue

is set to tell DbEntry how to judge the object is saved or not. In this case, if the
userID

equals 0, it means it is a new object, it should be used
INSERT

sql to operate, if not, it means it is a saved object,
it should be used
UPDATE

sql to
operate. This is how the
Save

function works.


The mutil
-
key example:

public

class

MKey : IDbObject

{


[DbKey(IsDbGenerate =
false
), Length(50)]


public

string

Name;




[DbKey(IsDbGenerate =
false
)]


public

int

Age;




public

bool

Gender;

}

The dynamic object also works on the class which is NOT inherits from
DbObjectModel
:

public

abstract

class

User : DbObject

{


public

abstract

string

Name {
get
;
set
; }

}



class

Program

{


static

void

Main(
string
[] args)


{


User u =
DynamicObject.NewObject<User>();


u.Name =
"mike"
;


DbEntry.Save(u);


}

}

The different of inherits form
DbObjectModel

or not inherits from it, is if a class inherits from
DbObjectModel
,
it has partial update feature supports. Otherwise no

this feature. More details about partial update will be
shown in
Partial update
.


All the object we just shows, all using the default informatio
n by itself like class name, field name and property
name, so we don't need to defind other information for it, but if we need , we can map it as another name:

[DbTable(
"User"
)]

public

class

MyUser : IDbObject

{


[DbColumn(
"Name"
)]


public

string

the
Name;

}

This class also defined to operate same table in database, but in C#, it has a different name. it could used for
sometimes we need to change table or column name by do not want change the C# code name. Or it can used

for some column name not a legal C# identity.

public

class

User : IDbObject

{


[DbColumn(
"User Name"
)]


public

string

Name;

}

The column can defined for some other attributes:

public

class

User : IDbObject

{


[Length(50), AllowNull]


public

string

Name;




[StringColumn(IsUnicode=
true
, Regular=CommonRegular.EmailRegular)]


public

string

Email;

}

The
Length

attribute defined the max length of the string field, it will using for generate create table sql
statement and using for validate f
unction.
Length

only works for string field, don't define it to other type field.


If a string field is not defined by
Length

attribute, it means it has unlimited size, the mapped database type is
"text" or "ntext".


The
AllowNull

attribute defined the fie
ld allow null value, in DbEntry, it also using for genernate create table
sql and for validate function. In DbEntry, the field which is defind
AllowNull

attribute or
Nullable

type field
will be deemed as allow null field. You don't need define this attribu
te to
Nuallable

field.


StringColumnAttribute

also works for create table and validate function.
IsUnicode

tell DbEntry if the
column type is unicode or not, by default, this argument is true, and the
Regular

tell the validate function if it
need check the

field by using a regular or not.
CommonRegular

provide two common regular: Email and Url.


By now, all fields we defined are mapped to a table column. In DbEntry, it works for field and property which
has both get and set. And it only works for public and

protected member. So if we want a member does not
map to a column, we can set it as private. Also, there is an attribute named
ExcludeAttribute
, the field or
property which defined by this attribute is not mapped to the table column too:

public

class

User

: IDbObject

{


public

string

Name;




[Exclude]


public

bool

isUserInput;




private

int

times;
// exclude too




public

int

code {
get

{
return

0; } }
// exclude too

}

IndexAttribute

is set to tell DbEntry

create index in create table function. It has 3 fields.
ASC

is bool type to
tell DbEntry which sort type of this index.
UNIQUE

is bool type to tell DbEntry if this index is unique.
IndexName

is string type to tell DbEntry what name of this index, if this
argument is not set, it will use “IX_” plus column
name as the index name. And if two or more columns set the same index name, it means it is a composed index.


The following code shows a composed index
Name_Age

with
DESC
,
UNIQUE

mode:

class

MyTest : IDbOb
ject

{


[DbKey]


public

long

Id = 0;




[Index(
"Name_Age"
, ASC =
false
, UNIQUE =
true
)]


public

string

Name =
null
;




[Index(
"Name_Age"
, ASC =
false
, UNIQUE =
true
)]


public

int

Age = 0;

}

The join table syntax is not in query syntax, it is an attribute set on object definition. The
DbTableAttribute

could use to set join table too.


The following code shows two table
SampleData

and
TheAge

join on
SampleData.Id

equals
TheAge.Id
:

[DbTable(
"Sam
pleData.Id"
,
"TheAge.Id"
)]

public

class

JoinTable1 : IDbObject

{


[DbColumn(
"SampleData.Id"
)]
public

long

Id;


public

string

Name;


public

UserRole Role;


public

DateTime JoinDate;


public

int

Age;

}

And there is another attribute to set joi
n with more details. This attribute is
JoinOnAttribute
. This attribute
should NOT set with
DbTableAttribute

together. It has more details like how to compare, which mode of join
to use.


Because we can join more than 2 tables, but we can not ensure the ord
er of the attributes we get by using .net
reflection, so it has an order argument to tell DbEntry the order of join syntax.


The following code shows 3 tables join by using
JoinOnAttribute
:

[JoinOn(0,
"SampleData.Id"
,
"TheAge.Id"
, CompareOpration.Equal,
JoinMode.Inner)]

[JoinOn(1,
"SampleData.Id"
,
"EnumTable.Id"
, CompareOpration.Equal, JoinMode.Inner)]

public

class

JoinTable2 : IDbObject

{


[DbColumn(
"SampleData.Id"
)]
public

long

Id;


[DbColumn(
"SampleData.Name"
)]
public

string

Name;


public

UserRole Role;


public

DateTime JoinDate;


public

int

Age;


[DbColumn(
"EnumTable.Name"
)]
public

string

EnumName;

}

There are 4 attributes for relation objects
--

HasOne
,
HasMany
,
BelongsTo
,
HasAndBelongsToMany
. These
attributes only works for abst
ract properties, if it defined on a normal property, it works just like
Exclude

attribute.


For the abstract property which defined these 4 attributes, also allowed
DbColumn

attribute too, if there is no
DbColumn

attribute on it, it using table name plus "
_Id" as the column name. And For the abstract property
which defined
HasOne HasMany HasAndBelongsToMany
, also
OrderBy

paramter in the 3 attributes could be
used for defined order by clause of relation SQL.

[DbTable(
"People"
)]

public

abstract

class

Person : DbObjectModel<Person>

{


public

abstract

string

Name {
get
;
set
; }




[HasOne(OrderBy =
"Id DESC"
)]


public

abstract

PersonalComputer PC {
get
;
set
; }

}



public

abstract

class

PersonalComputer : DbObjectModel<PersonalComputer>

{


pub
lic

abstract

string

Name {
get
;
set
; }




[BelongsTo, DbColumn(
"Person_Id"
)]


public

abstract

Person Owner {
get
;
set
; }

}

More details about relation object will be discussion in
Relations
.


And if there is an abstract function called
Init

or
Initialize
, it will be implemented automatically to initialize
all the fields. And the
parameter's name of init function is NOT case sensitive.


The following object defined normal fileds, the type of those fields include string, enum, DateTime, bool and
Nullable int and initialize function, by this point,
it will used for many samples of th
is tutorials
:

public

enum

UserRole

{


Manager,


Worker,


Client

}



public

abstract

class

SampleData : DbObjectModel<SampleData>

{


[Length(50)]
public

abstract

string

Name {
get
;
set
; }


public

abstract

UserRole Role {
get
;
set
; }


publi
c

abstract

DateTime JoinDate {
get
;
set
; }


public

abstract

bool

Enabled {
get
;
set
; }


public

abstract

int
? NullInt {
get
;
set
; }




public

abstract

SampleData Init(
string

Name, UserRole Role,


DateTime JoinDate,
bool

Enabled,
int
? NullInt);

}


2.

Configuration Common:


DbEntry mainly using
App.config/Web.config

to set the configure information of databases. First, it has a
section configure to define the new section
Lephone.Settings
:

<
configSections
>


<
section

name
=
"Lephone.Settings"

type
=
"Lephone.Util.Setting.NameValueSectionHandler,
Lephone.Util"

/>

</
configSections
>

It is fixed, so we don’t need to change it, just copy it to the
App.config/Web.config
.


And then, we need define the section
Lephone.Settings
, it is s
ame format as
appSettings
:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Access : @~test.mdb"

/>

</
Lephone.Settings
>

The above defined the default context to using
Access

and the short connection string is
~test.mdb
.


The configure information also can store as a embedded resource xml in the assembly, it is the same format as
it in
App.config/Web.config
, if the setting information is not find in
App.config/Web.config
, it will search
for assemblies to get it, if all fail
ed, it will raise an exception.


The file name of this embedded resource file must have the postfix ".config.xml". For example:

MyConfig.config.xml


This is an embedded resource xml configuration example:

<?
xml

version
=
"1.0"

encoding
=
"utf
-
8"

?>

<
configuration
>


<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Access : @~test.mdb"

/>


</
Lephone.Settings
>

</
configuration
>

The embedded resource xml configuration could be used sometime we can not set the configuration in
App.config/Web.config
, for

example, I used it in the unit test project, because it is a library and don’t know
who will load and run it.


There are some not usually used configure items:
SqlTimeOut
,
TimeConsumingSqlTimeOut
,
MaxRecords
,
Orm.UsingParamter
.


The
SqlTimeOut

and
TimeCon
sumingSqlTimeOut

are set for normal SQL calling from ORM layer, the timeout
of
SELECT

SQL will be set as
TimeConsumingSqlTimeOut
, and others will be set as
SqlTimeOut
. The default
value of
SqlTimeOut

is 30. The default value of
TimeConsumingSqlTimeOut

is 6
0.

<
Lephone.Settings
>


<
add

key
=
"TimeConsumingSqlTimeOut"

value
=
"3600"

/>


<
add

key
=
"DataBase"

value
=
"@Access : @~test.mdb"

/>

</
Lephone.Settings
>

There is a hidden mode of setting to set the mapped table name as another name. If we add the setting item
and the
key

is start with
@
, it will be a re
-
map setting. The value will be the final table name. Sometimes I used it
to change the table name of the

inner classes of DbEntry like
Lephone_Enum

and
LogItem
.

<
Lephone.Settings
>


<
add

key
=
"@Lephone_Enum"

value
=
"MyEnums"

/>

</
Lephone.Settings
>

If we using SQL directly, the timeout will be 30 and we can change it manually.

SqlStatement sql =
new

SqlStatement(
"select count(*) from [User]"
);

sql.SqlTimeOut = 180;

DbEntry.Context.ExecuteScalar(sql);

The
MaxRecords

is set for
SELECT

SQL the max records count we will load, if this value is 0, it is unlimited, the
default value is 0. This setting item could be used in some special time like
SQL QUERYER
, the SQL is input by
end user, and we don’t want the result will be unlimited to del
ay our database response performance.
Otherwise, let it be 0.


The
Orm.UsingParamter

is set for how to give the information by clauses. By default, this value is true. It
means it will use SQL Parameter to send the information to database. If the value is
false, it will replace the SQL
Statement parts as the information, but it is not fully test, and doesn’t support all types. I used this setting only
if I want see the whole SQL and don’t mind the result.

Working with databases:


The following is how to set database context in config file.


DataBase

joins with two part, first is
Dialect
, last is
ConnectionString
, split with ":". If the first of char of
Dialect

is @, it's a short style, and means it is a inner
Dialect
,
ConnectionStr
ing

for
Access
,
Excel
,
SQLite
, if the first char is @, it's a short style, just put the file name after @.


If there is
{BaseDirectory
} or
~

in short style
ConnectionString
, it will replace to current directory of this
application (or web), so please ensur
e there is no
{BaseDirectory
} or
~

in
ConnectionString

you don't want.


For
SQLite
, the short style set cache to 100K and do not use system
Flush

function.
(The origin provider set
cache to 2K and use system Flush function.)


The
UnitTest

using
SQLite
, to
run it, you should install the
SQLite

provider first.


DbProviderFactory

should set
DbProviderFactory

fullname, for
@SmartDbFactory
, it join with two part, last
is Assembly fullname,
SmartDbFactory

will search driver automaticly, it could be use as suport
the driver of
ADO.Net 1.x , and, it also provide search Stored Procedure's paramters.


Assembly's fullname could be get by
AssemblyNameGetter.exe

in the samples.


The sample of config:


Access 2003:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Access :

@~test.mdb"

/>

</
Lephone.Settings
>

Access 2007:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Access2007 : @~test.accdb"

/>

</
Lephone.Settings
>

Excel:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Excel : @~test.xls"

/>

</
Lephone.Settings
>

Excel
2007:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Excel2007 : @~test.xlsx"

/>

</
Lephone.Settings
>

Sql Server 2000:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@SqlServer2000 : data source=wms;initial catalog=wms;user
id=sa;password=1"

/>

</
Lephone
.Settings
>

Sql Server 2005:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@SqlServer2005 : data source=wms;initial catalog=wms;user
id=sa;password=1"

/>

</
Lephone.Settings
>

MySql:
http://dev.mysql.com/downloads/connector/net/5.1.html

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@MySql : server=localhost;user id=root; password=1;
database=wms; pooling=false"

/>


<
add

key
=
"DbProviderFactory"

value
=
"@SmartDbFactory : MySql.Data
, Version=5.1.2.2,
Culture=neutral, PublicKeyToken=c5687fc88969c44d"

/>

</
Lephone.Settings
>

SQLite:
http://sourceforge.net/project/showfiles.php?group_id=132486

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@SQLite : @~Test.db"

/>


<
add

key
=
"DbProviderFactory"

value
=
"System.Data.SQLite.SQLiteFactory,
System.Data.SQLite, Version=1.0.60.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139"

/>

</
Lephone.Settings
>

Firebird:
http://www.firebirdsql.org/index.php?op=files&id=netprovider

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Firebird :
User=SYSDBA;Password=masterkey;Database=c:
\
mytest.fdb;DataSo
urce=localhost;Port=3050;Dial
ect=3;Charset=NONE;Role=;Connection
lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0"

/>


<
add

key
=
"DbProviderFactory"

value
=
"@SmartDbFactory : FirebirdSql.Data.FirebirdClient,
Version=2.0.1.
0, Culture=neutral, PublicKeyToken=3750abcc3150b00c"

/>

</
Lephone.Settings
>

Oracle:

<
Lephone.Settings
>


<
add

key
=
"DataBase"

value
=
"@Oracle : Data Source=localhost; User Id=llf; Password=123"

/>


<
add

key
=
"DbProviderFactory"

value
=
"@SmartDbFactory :
System.Data.OracleClient,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

/>

</
Lephone.Settings
>

PostgreSQL:
http://pgfoundry.org/projects/npgsql

<
Lephone.Settings
>


<
add

key
=
"DataBase
"

value
=
"@PostgreSQL :
Server=127.0.0.1;Port=5432;Database=postgres;Userid=sa;password=1234;Encoding=UNICODE;"

/>


<
add

key
=
"DbProviderFactory"

value
=
"@SmartDbFactory : Npgsql, Version=1.98.4.0,
Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"

/>

</
Lepho
ne.Settings
>

Attention:

The version of database provider is based on my installed version, if you installed a new version of
the provider, please change the version part. If it did not installed to the GAC, please do it by yourself.


Auto create table:


Another setting
AutoCreateTable

is set to tell DbEntry to create table if it doesn’t exist. The default value is
false.

<
Lephone.Settings
>


<
add

key
=
"AutoCreateTable"

value
=
"true"

/>


<
add

key
=
"DataBase"

value
=
"@Access : @~Test.mdb"

/>


<
add

key
=
"Access2007.AutoCreateTable"

value
=
"true"

/>


<
add

key
=
"Access2007.DataBase"

value
=
"@Access : @~Test.mdb"

/>

</
Lephone.Settings
>

If it is activated, when some code want access database by using object model, DbEntry will try to create the
table first if i
t doesn't exist.


This feature only works when the table doesn't exist, it doesn't judge columns.


This feature only works for ORM functions, execute SQL directly doesn't raise it.


This feature will help us to implements application prototype faster, it s
hould only used in development or test.


When the application deployed to the working environment, change the value as false or delete this line in
config file.

Attention:

MySql

and Firebird don't have Unicode type of string, so if you specify the string column as Unicode
type in object model, the created column size maybe not what we thought.


Default context


DbEntry.Net allows user pre
-
setup some database connections and set

one of them as the default context.


The following config file shows 3 phases of project, and the current selected is
development
:

<?
xml

version
=
"1.0"

encoding
=
"utf
-
8"

?>

<
configuration
>


<
configSections
>


<
section

name
=
"Lephone.Settings"

type
=
"Lephone.Util.Setting.NameValueSectionHandler,
Lephone.Util"

/>


</
configSections
>


<
Lephone.Settings
>


<
add

key
=
"DefaultContext"

value
=
"development"

/>


<
add

key
=
"test.DataBase"

value
=
"@Access : @~WMStest.mdb"

/>


<
add

key
=
"development.DataBase
"

value
=
"@Access : @~WMSdevelp.mdb"

/>


<
add

key
=
"SqlServer.DataBase"

value
=
"@SqlServer2005 : data source=wms;initial
catalog=WMS;user id=sa;password=1"

/>


</
Lephone.Settings
>

</
configuration
>


The following config file stored some databases connectio
ns infomation in it, and the current context is
Access
:

<?
xml

version
=
"1.0"

encoding
=
"utf
-
8"

?>

<
configuration
>


<
configSections
>


<
section

name
=
"Lephone.Settings"

type
=
"Lephone.Util.Setting.NameValueSectionHandler,
Lephone.Util"

/>


</
configSections
>


<
Lephone.Settings
>


<
add

key
=
"DefaultContext"

value
=
"Access"

/>


<
add

key
=
"Access.DataBase"

value
=
"@Access : @~test.mdb"

/>


<
add

key
=
"Excel.DataBase"

value
=
"@Excel : @~test.xls"

/>


<
add

key
=
"SqlServer.DataBase"

value
=
"@SqlServer2005 :

data source=wms;initial
catalog=WMS;user id=sa;password=1"

/>


<
add

key
=
"MySql.DataBase"

value
=
"@MySql : server=localhost;user id=root;
password=123; database=mytest; pooling=false"

/>


<
add

key
=
"MySql.DbProviderFactory"

value
=
"@SmartDbFactory : MyS
ql.Data,
Version=5.1.2.2, Culture=neutral, PublicKeyToken=c5687fc88969c44d"

/>


</
Lephone.Settings
>

</
configuration
>


Emit or Relection:


By default, DbEntry
(0.32)

will use Emit mode to operate object.
(But for some reason, Access will force to use
reflection mode.)

With this mode, we will get high performance, but it has some restricts: the protected field
should set as "internal" too, and the assembly which has protected field(s) in the object model(s) also should set
as friendly assembly with "DbE
ntry_MemoryAssembly".


Or if there is compatibility problem, maybe we want using reflection too.


We can just set it in config file:

<
Lephone.Settings
>


<
add

key
=
"ObjectHandlerType"

value
=
"Reflection"

/>

</
Lephone.Settings
>

And, set a

assembly as friendly assembly with "DbEntry_MemoryAssembly" need defind following in
"AssemblyInfo.cs":

[assembly: InternalsVisibleTo("DbEntry_MemoryAssembly, PublicKey=00240000048000009400000

00602000000240000525341310004000001000100ebce81d3bd5481a9f6266
6c880d1425968d3074786f29f3

8f5f42ba7d2497ac56456084097085b82f8980304dd9048da30716d8bcfd920a24a4cee2580fd09cecbe40f7

eb8e7211e3e3f592f3aba3b38268c99e124525e7a200015e3ee1e061e6f1387ac474577b8023af58c3bbcc79

0f26b1745b454862ada11213b130097ef")]


It should be
in the single line.


We don't need defind it if we don't have the protected
(internal)

field in object model we defined. So mostly we
can forgot about it. :)


If we always using abstract property to define the model object, we will never need to worry abou
t it.

3.

Mapping relations


Field

Column

int Column


int

long Column


bigint

short Column


smallint

byte Column


tinyint

Guid Column


uniqueidentifier

bool Column


bit

DateTime Column


datetime

decimal Column


decimal

float Column


real

double Column


float

byte[] Column


binary

string Column


ntext

[StringColumn(IsUnicode = false)]string Column


text

[Length(30)]string Column


nvarchar(30)

[StringColumn(IsUnicode = false), Length(30)]string Column


varchar(30)

III.

Details: