Marius Gheorghe

Building software : make it work, make it good, make it fast

Customizing the CLR

Finished reading the book. It was a good read. Not really useful stuff for a "managed only" developer.
Actually you would love this if you have to write a "customized" CLR host. It's really interesting
how much work went into the CLR so it can be hosted inside SqlServer.
   My gripe is related to the customization of the CLR using the config file. We can't, for instance,
even customize the size of the thread pool. I'm not expecting to have custom task schedulers for CLR
using the config file but a little more controls over the CLR world be very appreciated. Anyway, for now,
if you want the good stuff you must write a CLR host.
  So the book is pretty good and well written. Recommanded.

ClickOnce - death of ASP.NET applications ?

At least ASP.NET applications for the intranet. I confess that i worked
on both Windows Forms and ASP.NET apps. As a user(and also as a programmer)
i prefer the first ones.The usability of the ASP.NET gives a lot to be desired.
The are slow and cluncky.I would choose a normal Windows Application over the
ASP.NET equivalent any time.
  In the intranet scenarios the only advantage of the ASP.NET apps is the deployment.
Deploy on server and forget about it. Update on server and everyone has the latest version.
Not so with Windows apps. It looks like ClickOnce is set to change some of that. I am
saying "some" because i'm not sure that ClickOnce will work in complex deploying
scenarios (for instance installing COM+ applications, adding assemblies to GAC etc).
The only demonstrations for ClickOnce i've seen were some "dinky single window form
app" on Channel9. Btw MS guys, when you do demos, it will give you a WAY better credibility
if you demo with more "Real life" apps instead of toys.
  So, it seems that with .NET 2.0, we will be able to deploy/update Windows Forms apps as
easy/fast as ASP.NET. Will this be the death of ASP.NET apps for intranet ?

I certainly hope so.

 

C# 2.0 dislikes

Some dislikes on C# 2.0 :

- no support for operator constraints in generics.
  This is pretty bad from my point of view. In one of my project i have quite
a few structs which have the primary operators(+, -, *, /) overloaded. Unfortunately
i can’t write generic code for these using the operators because there is no way to
add operator constraints.

- Nullable types implementation suck.
   The implementation is NOT clean. It shouldn't be a difference in syntax between
a nullable int and a regular int. No NullableType<int> thingie. Writing "generic" code which
works with both int and int? is hard because you always have to check for the nullable
or you have the use the butt ugly "??" operator.
  A conversion to the default value (in case of int is 0) should be done automatically.
We should not need the "??" operator for that.  The whole ideea of a nullable type is to
check his "nullability" ONLY when i need. I shouldn't be force to "??"it so i can use it
as a regular type.   

Mapping objects

There are 2 ways to map objects to database schemas: 1. normal classes. These are classes who don't have a super class (besides System.Object). The mapping is held externally in a single xml config file (or you can have a single file for each database table schema). They can look like this
public class Person { public int Id { //get-set } public string Name { //get-set } }
The advantage of this model is that you have the "clean" model. No methods, no nothing....just the clean model. The disadvantages are : - external dependencies (the xml mapping file(s)). - informations about the mapped object are found in external classes. This usually creates a cumbersome API. For instance if you want to now if the Name is null you'll have something like
//check for null. IsNull(p, "Name");
- fool around with xml files to update the changes in the database schema. - the overhead of the mapping information. Usually the mapping info is read when needed and cached for subsequent needs. The mappinf indo for a single table is not much but when you cache the mapping information for 100 tables the situation changes. 2. The mapping is done "in code" and the class inherits from a super class. This is the approach i have taken with DataBlock. You have a super class (called TableMetadata) and all the mapped classes inherit from it
public class Person : TableMetadata { //generated implementation }
The advantages of this model are : - you don't write anything. You don't fool around with xml files and you don't write the class definition. Everthing is generated for you based on the database schema. It's a few seconds process. - no external dependencies. Everything compiles into an assembly. - no overhead of mapping information. Because the mapping info is "in code" the code just runs. No need to read (and cache) at runtime the mapping info from the xml file. - information is part of the mapped object. You don't pass an instance of the object to an "external" API. Taking the above example....if you want to know if a certain field has a null value :
p.IsNull("Name");
or by index
p.IsNull[1];
This is both an advantage and the only disadvantage that the model has. It's a disadvantage because the "mapped object" is not clean anymore. Besides the mapping object information you also have methods to "query" the mapped objects for informations. But the adavantage of beeing much faster (direct calls vs xml reading + reflection) clearly overweights the disadvantage.

Writing object oriented queries

Any OR/M tool which abstracts multiple RDBMS needs a "RDBMS neutral language" which allows
the programmers to express queries. When i started thinking about this in
DataBlock one of my first thoughts was : I'll implement OQL for DataBlock.
   Except there is a slight problem with OQL......nobody seem to give a rat's
ass about it. The "regular" .NET programmer doesn't even know what OQL is.
So i had to skip OQL (for now....if there are enought request i might add support for OQL) 
and i had implemented an OO way to express queries in DataBlock.It looks like this :

Product prod = new Product();  //the mapped object.
QueryCriteria qc = new QueryCriteria(prod);  //query criteria

The above will select all the fields from the Product table. To select partial
fields you can use:

QueryCriteria qc = new QueryCriteria(prod.TableName, prod.TableFields[0],prod.TableFields[1]);

Adding criterias to the query is simple :

qc.Add(CriteriaOperator.Smaller, prod.TableFields[0], 36);
qc.Add(CriteriaOperator.Higher, prod.GetField("SupplierId"), 50);
qc.Add(CriteriaOperator.Like, prod.TableFields[1], "Chai");

The query criteria above "translates" into the following SQL:

SELECT Products.ProductID, Products.ProductName, Products.SupplierId, Products.
       CategoryId, Products.QuantityPerUnit, Products.UnitPrice, Products.UnitsInStock,
       Products.UnitsOnOrder, Products.ReorderLevel, Products.Discontinued
FROM Products
WHERE
 Products.ProductId < 36 AND
 Products.SupplierId > 50 AND
 Products.ProductName LIKE 'Chai%'

  Another feature of the QueryCriteria is field aliases. You can express this with :

qc.AddAlias(prod.GetField("Name"), "ProductName>");
 
  The last feature i would like to write about is the join feature. Of course the
query criteria must allow joins. Let's suppose that the Product table has a 1:m
relation with the Suppliers. The query criteria can look like

Suppliers sp = new Suppliers();
QueryCriteria qcSupplier = new QueryCriteria(sp);

QueryCriteria qcProduct = new QueryCriteria(prod);
qcProduct.AddJoin(JoinType.Inner, prod.GetField("SupplierId"), sp.GetFiled("SupplierId"), qcSupplier);

  It's quite simple. We add the child criteria (qcSupplier) to the criteria of the main
tale (qc). The result is a join between the two tables.

  So there you have....the result is a nice, clean, object oriented way of writing queries.

Welcome

Hello,

Welcome to my new .NET blog. I, finally, switched to b2evolution and i’ll promise to blog more often about my personal projects and other .NET related stuff.

 

 

 

NET books

   I've finished reading Chris Sells ""Programming Windows Forms in C#"" last night and...well i was kind of dissapointed. It's not a bad book but frankly i was expecting more. More ""hardcore content"". Stuff that i can't find in the docs. A big chunk of the book was ""fluff"" that you can find in the SDK. Anyway if you're interested in WinForms and you are a newbie you should grab it. If you aren't a newbie....hold on to your money. 

 Now....related to the .NET books. Is it just me or most of them just plain suck ? I mean....the ""regular"" .NET book seems to be just a rewrite of the SDK. Let's take the ADO.NET books...what informations do you find in, from the top of my head, ""ADO.NET cookbook"" that you can't find in the docs jQuery15208434510290844962_1350449720748? The best .NET book....definetly Essential .NET by Don Box. Highly recommanded. What's your favourite .NET book ?

Karmencita object query language for .NET released

1

I have finally released the latest version.  Karmencita is a high level object query language for .NET . It's purpose is to allow easy querying from in memory structured data.

Features :

- easy, SQL like language.

- common, slim API used for querying data.

- supports any IEnumerable data source, DataTables and XmlDataDocuments.

- extensible implementation

- common API but still get results depending on the data source. (for instance when querying XmlDataDocuments we get back XmlElement[]. But if we query a DataTable we get back a DataRow[]).

- supports IComparable for custom type implementation.

Samples :

-query a generic list of Customers :

//get a list of customers
List<Customer> list = ………

ObjectQuery<Customer> oq = new ObjectQuery<Customer>();

string query = “Name=[Marius Gheorghe] and IsMale=true and Age > 10”;

Customer[] custom = (Customer[]) oq.Select(list, query);

 

 - query a DataTable (the Northwind database products table)

//load the DataTable from the database
DataTable dt = ………

ObjectQuery<DataTable> oq = new ObjectQuery<DataTable>();

string query = “Name=[Salted Pork Meat] and Discontinued = false and UnitPrice > 12”;

DataRow[] rows = (DataRow[]) oq.Select(dt, query);

- query a XmlDataDocument

//load the XmlDataDocument
XmlDataDocument dt = ………

ObjectQuery<XmlDataDocument> oq = new ObjectQuery<XmlDataDocument>();

string query = “Name=[Salted Pork Meat] and Discontinued = false and UnitPrice > 12”;

XmlElement[] rows = (XmlElement[]) oq.Select(dt, query);

 

The web site is located at www.voidsoft.ro/karmencita.html

This is free software (LGPL).

 

Now playing: Amorphis - House Of Sleep