Monday, November 29, 2010

Linq to NHibernate: no data layer!

NHibernate 3 includes Linq. These two combined makes your datalayer 'dissapear'. In the following example I'll show you how to set up your entities in a way you can reference them from your code without any knowledge of the underlying database and database model.
I will give this example with the widely known Northwind database.

On the right a picture shows an outline of the project. NortwindEntities is a .NET 3.5 Class library with references to NHibernate 3.

There are two folders: one containing the entities (objects), and one containing the mapping files used by NHibernate to map the entities-logic to the relational database. The final file is called NortwindContext.cs. This file contains functionality to setup a SessionFactory and a Session. The depended file (actually a partial class) NortwindContext.Entities.cs holds properties to access the entities of the context in a proper way. For example in Linq to NHibernate the Customer entity is referenced as:


session.Query<Customer>();

The NorthwindContext has a property Customers:

public IQueryable<Customers> Customers
{
get { return Session.Query<Customers>(); }
}

Setting up this Class library is the difficult part. But when it is done, you can reference it from your application. With two lines of code you have set up the Context (including the connection to the database)



// Set up the servername once
NorthwindContext.SetSQLServer(".\\SQLExpress");
// Create a new context
var nc = new NorthwindContext(true);

Retrieving your entities is as simple as:



var customers = nc.Customers.Select(c =>
new { c.ContactName, c.Orders.Count });

Saving your entities isn't that hard anymore:



var customer = new Customer
{
Id = "FOE",
ContactName = "Frank",
City = "Dalem"
};
nc.SaveOrUpdate(customer);
nc.Flush();

Conclusion: The datalayer kind of dissapeared.


You can download the example solution here. It also includes the SQL-script to generate the Northwind database in your SQL Server (express) enviroment.

Friday, November 05, 2010

Client side confirmation in asp:CommandField

When you have an asp.net gridview (framework 3.5) on your page, which includes a column of "asp:CommandField" there is no option to control any client-side behaviour with the designer. I wanted a client side confirmation when a user pressed the delete icon which I placed by asp:CommandField ButtonType="Image" DeleteImageUrl="~/images/del.png" ...

There is a way to add client side confirmation to the asp:CommandField delete action. This is done by injecting javascript into the generated ImageButton in the OnRowDataBound event of the gridview. In the example below, the code loops through all the controls in the last cell of the row (there is where I have the asp:CommandField). If the control is an ImageButton and it has the CommandName "Delete" then set the OnClientClick property to a javascript call.


protected void grdItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.Cells.Count > 1)
{
var ctls = e.Row.Cells[e.Row.Cells.Count - 1].Controls;

foreach (var c in ctls)
if ((c is ImageButton)
&& (((ImageButton)c).CommandName == "Delete"))
((ImageButton)c).OnClientClick =
"if (!window.confirm('Are you sure')) return false;";
}
}

Thursday, September 23, 2010

Aggregate string with Linq

Linq gives you the standard aggregate function like sum, average, max, etc. But if you want (for some reason) want to concatenate some string-values in a group by it is not possible with a build-in operator.

The following code shows an example of how to group a list of values and aggregate a list of strings to a comma separated line with unique values.



var orderList = new List();
var c = new Customer { Name = "Frank" };
orderList.Add(new Order {Customer = c, Amount = 2, Price = 1.99 } );
orderList.Add(new Order {Customer = c, Amount = 4, Price = 1.59, Note = "Discrete" } );
orderList.Add(new Order {Customer = c, Amount = 1, Price = 21.00 } );
orderList.Add(new Order {Customer = c, Amount = 80, Price = 0.99, Note = "Before Xmas!!" } );

c = new Customer { Name = "John" };
orderList.Add(new Order {Customer = c, Amount = 9, Price = 1.99 } );
orderList.Add(new Order {Customer = c, Amount = 14, Price = 2.59, Note = "Call when send" } );
orderList.Add(new Order {Customer = c, Amount = 7, Price = 26.95 } );
orderList.Add(new Order {Customer = c, Amount = 90, Price = 0.99 } );

var q = orderList
.GroupBy(order => new { order.Customer.Name },
(customer, orders) => new {
customer.Name,
Totalprice = orders.Sum(o => o.Price),
Notes = string.Join(", ", orders
.Where(o => string.IsNullOrEmpty(o.Note) == false)
.Select(o => o.Note).Distinct().ToArray())
});

q.Dump();

Linqpad will give this output:



Friday, May 07, 2010

SQLite and .NET 4.0

When I converted an existing C# solution with NHibernate/SQLite to .NET 4, I got the following runtime exception:
Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4.

The cause is that the System.Data.SQLite.dll is compiled against .NET 2. To avoid this problem, you can add te following configuration in your app.config:



and the application runs fine.

Thursday, May 06, 2010

MapXtreme hide legend items

In some cases you do not want certain features shown in your legend of a map.

Setting the property of Thematics.IndividualValueTheme.Bins(0).LegendRow.Visible to false will not work in MapXtreme 6.8.
This is a known bug and there is no patch.
However when you create a ThemeLegendFrame based on this IndividualValueTheme you can hide items from the legend by
Legends.ThemeLegendFrame.Rows(0).Visible = false

Monday, February 08, 2010

Snow Leopard takes too long to sleep (not anymore)


Usually it takes my iMac about 1 or 2 seconds to sleep (hibernate). Today it took about 25 seconds. I turned off my mac, started it again, but still it took about 25 seconds to sleep.

You can use the command pmset -g log to figure out whats happening when the mac goes to sleep. In my case I noticed an "applicationresponse.timedout" in this log for the process cupsd. This is the printer-deamon. Viewing the status of my printer I noticed a document I printed yesterday, which hasn't come out because the printer ran out of paper. Removing this item from the print-queue resulted back in a mac which went to sleep in 1-2 seconds.

Friday, January 29, 2010

ORA-06413 Connection not open.

I'd moved the source files from a c# .net application on my filesystem. When I openened the solution in VS2008 and started it I got the following error "ORA-06413 Connection not open."

Solution to this problem: One of my folders had an opening parenthesis "(". Removing this parenthesis solved the problem!

Monday, January 18, 2010

Dag MCE, hallo XBMC !


Ik gebruikte Windows XP MCE al voor een tijdje voor het afspelen van mijn media. Mooie hiervan was dat ook uitzending gemist via online spotlight benaderbaar was. Tot voorkort ... Ineens gaf het de melding dat dit niet gesupporteerd was. Bij het volgen van de help kwam ik op een MS-website die mij doodleuk meldde dat ik moest upgraden naar Windows 7 ! Dit houdt voor mij in dat ik ook mijn hardware moet upgraden; dus niet!

Ik ben via Plex voor de Mac terecht gekomen op de site van XBMC en door middel van deze plugin kan ik gewoon uitzendinggemist kijken op mijn "oude" mediacenter. Het is met XBMC niet mogelijk om programma's op te nemen via een TV kaart, maar het doet verder niet onder voor MCE. Tevens zijn er veel plugins verkrijgbaar op deze site.