Tuesday, May 15, 2007

This is our first user supplied EntitySpaces blog post. We hope to do more of these in the future as we have some customers doing some pretty cool stuff with the EntitySpaces architecture. A special thank you goes out to Robert Campbell of ecomment ltd. See Robert's bio at the end of this post. - The EntitySpaces Team.


In this article we’ll develop an application for a Windows Mobile ("WM5") platform device. While the application is just an example, and some would argue an incomplete one at that, we will be able to see all the necessary steps to get started with EntitySpaces (“ES”). We’ll also see how to use data source binding on a couple of 3rd party controls. You can also see a FLASH DEMO as well.

Getting Started

Prerequisites: What you need

    • Microsoft SQL Server Compact Edition
    • Microsoft SQL Server 2005
    • MyGeneration Version 1.2.0.6
    • EntitySpaces 2007 Beta v0.0507
    • Visual Studio 2005 with Windows Mobile 5 SDK installed
    • Resco AdvancedList.NET. See http://www.resco.net/products/

Create a new VS Project for Windows Mobile 5

In Visual Studio (“VS”), Clicking ‘File’ > ‘New’ should produce the New Project dialog below . I’ve selected ‘Windows Mobile 5.0 Pocket PC’, ‘Device Application’, and changed the Name to ‘Demo’.

Clicking OK at this point should result in a new project called Demo with a single blank form.

The interesting things to notice here are the default references VS implements because we’ve targeted the WM5 platform.

Create a Database

Creating a database file for use in our application is relatively simple if MS SQL Server has been installed properly.

In VS, Click the project icon in the solution tree (shown above as ‘Demo’), Right-Click, and Click ’Add’ > ’New Item...’. Select ‘Database File’ in the Add New Item dialog.

I changed the Name of the database file to Demo.sdf.

Click ‘Add’, and the standard VS Data Source Configuration Wizard pops up.

We’ll not need this as we’re going to use ES!!

Click ‘Cancel’ instead.

Double-Click the database file that appeared in the Project Solution Explorer tree.

The Server Explorer pane should now appear in your VS IDE.

If the connection to the database is closed (indicated by the little red ’x’ next to the Demo.sdf database icon), Right–Click and Clicking ’Refresh’ should restore it.

We can now build the database proper.

Right-Click on the Tables icon. Click ‘Create Table’. This will present a familiar New Table Dialog.

In this screenshot I’ve created a table called Survey and added the 5 columns.

Note the Id column is a Unique Identifier, is set as the Primary Key, is a ‘RowGuid’, and it’s practical to set the default value for the column as (newid()).

Create a second table which will be used as a related table. In this demo we’re going to use a table called HTypes (house types) for our survey.

We need to relate the two tables with some foreign key constraints. In SQL server ‘proper’ this is easily done with the relationship diagram tool in VS. However, with SQL CE or ‘Compact Edition’ as it’s now called, that’s not possible. We’ll have to do this programmatically with a TransactSQL Query.

SQL Reference (SQL Server Compact Edition) 

http://msdn2.microsoft.com/en-us/library/ms173372.aspx

I usually have to resort to the Microsoft SQL Server Management Studio to run this query as the VS component doesn’t support the ‘ALTER’ command (Anyone have any idea why? Or, indeed, why the Management Studio doesn’t support the ability to ‘Open’ tables?)

To add a constraint to the Survey table, we need to run this query:

ALTER TABLE [Survey] ADD CONSTRAINT [FK_Survey_HTypes] FOREIGN KEY([HouseType]) REFERENCES [HTypes] ([Id])

Note, in this simplified demo, I have just taken the defaults for the behavior for this constraint. A lot of this will depend on your real application. I’m no DB expert, and this is an ES demo.

At this point we have:

  • A WM5 VS project shell.
  • An SQL-CE database with tables and FK Table Constraints.

Let’s add two folders to our VS project for the files generated in the next section. Click the Project icon in the solution tree. Right-Click and Click ’Add New Folder’. Add a folder called ‘Generated’ and another called ‘Custom’.

Note the highlighted Project Folder property. You’ll need this information in the next section. The next step is to produce the ES generated classes.

MyGeneration

Start MyGeneration, and select ‘Edit’ > ‘Default Settings...’.

Click ‘Microsoft SQL CE’ from the ‘Driver’ dropdown. The easiest place to get the Connection String is by copying it from the properties dialogue of the Demo.sdf file in VS, and pasting it in the text box here. Click ‘SqlServerCe’ in the ‘DbTarget’ dropdown. Optionally, click your preferred language in the ‘Language’ dropdown, in this case, ‘C#’.

Click ‘Test Connection’ to confirm a valid connection can be established.

Click the Templates Tab of the dialogue.

All we really need to change here is the Default Output Path.

Copy the Project Directory path that was noted in the previous screenshot, and paste it to the Default Output Path here. The template will automatically find the Generated and Custom directories.

Click OK. This should start the connection to your database.

You should now be able to select and expand the MyMeta tree to show the database we have created in all its glory.

Go Generate!

Select the Template browser from the icons at the top of the left hand side of the MyGeneration IDE. Expand the EntitySpaces folder and the C# folder below that.

We’re going to run two templates:

  • Custom Classes Master (C#)
  • Generated Classes Master (C#)

We’ll Double-Click a template to load it, and click the green ‘go’ arrow to generate. Let’s start with the Custom Classes.

Custom Classes Template

Note the template has automatically selected the \Custom\ folder.

The Namespace defaults to ‘BusinessObjects’. Change this to ‘Demo’.

Ctrl-Click both tables to select them in the Select Tables window. Click the OK button/bar.

If everything goes according to plan, the output will be shown in the output tab / window.

Generated Classes Template

Double-Click on the Generated Classes Master template and Click the green ‘go’ button again.

This dialogue has two tabbed sections.

For the Basic Information tab, make the same edits as for the Custom Classes template. Again, the Output Path should be automatically filled in for you.

Click the Advanced Options tab.

On this tab we need to check the options as shown:

Important: The Ignore Schema, Ignore Catalog, and Target Compact Framework boxes need to be checked.

Click OK.

Again, if it’s worked, the output should show in the pane on the right.

We’re done with MyGeneration, either close or minimize the application.

Incorporating the generated code into the VS project

Go back to VS, and Click the ‘Refresh’ icon. Click the ‘Show All Files’ icon.

We now can see our generated files in both directories but grey’d out. As yet, they’re not part of the project.

Highlight them all using the usual Shift-Click and/or Ctrl-Click techniques. Right-click one of the highlighted files, and Click ‘Include In Project’.

Hey! Just before you go clicking ‘Build’, we need to do one more thing. Add the ES references to the project.

To do so, Click the References node in the solution tree, Right-Click and Click ‘Add Reference...’.

At this point, the current documentation suggests that the ES DLLs will be there ready to select. In my case, they were not, so Click the Browse tab and drill down to the CE directory in the place where EntitySpaces is installed. The default, and in my case, is:

C:\Program Files\EntitySpaces\Redistributables\CE

The Add Reference dialogue should look like this:

We need to Ctrl-Click Core.Ce, Interfaces.Ce, LoaderMT.Ce, and SqlClientProvider.Ce. Then, Click OK.

Your Solution tree should now look like this:

Quick! Click ‘Build’ before you collapse in anticipation!

‘Build Succeeded’

“Ah”, you cry, “It looks great, but doesn’t do anything!”

Wait… there’s more....


Adding some code!

Program.cs

The application needs to have added the medium trust loader, and, because we need a configless implementation in WindowsCE, Program.cs needs to look something like this.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using EntitySpaces.Interfaces;
using EntitySpaces.LoaderMT;

namespace Demo
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main()
        {
            // --- Manually register a connection (DO THIS ONE TIME ONLY) ---
            esConnectionElement conn = new esConnectionElement();
            conn.ConnectionString = @"Data Source=\program files\Demo\Demo.sdf;";
            conn.Name = "Demo";
            conn.Provider = "EntitySpaces.SqlClientProvider.Ce";
            conn.ProviderClass = "DataProvider";
            conn.SqlAccessType = esSqlAccessType.DynamicSQL;
            conn.ProviderMetadataKey = "esDefault";
            conn.DatabaseVersion = "2005";

            // --- Assign the Default Connection ---

            esConfigSettings.ConnectionInfo.Connections.Add(conn);
            esConfigSettings.ConnectionInfo.Default = "Demo";

            // --- Register the Loader ---

            esProviderFactory.Factory = 
new EntitySpaces.LoaderMT.esDataProviderFactory(); Application.Run(new Form1()); } } }

Form1.cs

Our ‘spec’ calls for a form that displays a grid with all the survey results, so we should add a grid. We’re going to use a 3rd party specialist grid, the Resco AdvancedList, and a panel to display the record with all its detail. Here, I’ve used the Resco DetailView.

Initializing our form

Of the many things to do to the form, the first is to add the two ES collections by dragging the icons from the toolbox to the form. Using this method, all the necessary defaults are created and end up in the designer.cs file.

I’ve also done a similar thing with the two Resco controls; the advanced list and the detail view.

I've created a method to initialize the form:

private void init()
{
    // The Grid is populated with the collection of surveys
    // just get everything; 
    if (surveys.LoadAll())
    {
        this.advancedList1.DataSource = surveys;
        this.advancedList1.Refresh();
    }
   else 
   {
        MessageBox.Show("can't load survey data");
   }
}

The record detail is displayed in a control called DetailView, We need to populate the combobox on the related field, load the collection, and bind it to the ComboBox

 

private void init()
{
    // The Grid is populated with the collection of surveys
    // just get everything;                           
    if (surveys.LoadAll())
    {
        this.advancedList1.DataSource = surveys;
        this.advancedList1.Refresh();
    }
    else 
    {
       MessageBox.Show("can't load survey data");
    }

    if (types.LoadAll())
    {
        //This sets the DataSource of the ComboBox to the collection
        ((Resco.Controls.DetailView.ItemComboBox)this.detailView1.Items["HType"]).DataSource 
= types;
((Resco.Controls.DetailView.ItemComboBox)this.detailView1.Items["HType"]).DisplayMember
= HTypesMetadata.PropertyNames.Htype;
((Resco.Controls.DetailView.ItemComboBox)this.detailView1.Items["HType"]).ValueMember
= HTypesMetadata.PropertyNames.Id; this.detailView1.Refresh(); } }

By the time we exit this method, we've done everything to populate the grid, and related fields, in the record detail display... in 12 lines of code... and NO SQL or recordset/dataset stuff to remember.


Display the Record Detail

Using the AdvancedList ("AL") to allow a user to select a record to display, we have a method showDetails. This method uses the Id of the record as its parameter. This is usually called by a row select event handler on the AL.

private void showDetails(Guid rowToEdit)
{
    s = new Survey();
    s.LoadByPrimaryKey(rowToEdit);
    this.detailView1.DataSource = null;
    this.detailView1.DataSource = s;

    this.detailView1.Refresh();
}

The method simply creates a new Survey entity, and loads it with the record data using the ES LoadByPrimaryKey() method. This binds the resulting object to the DetailView control through the assignment of the DataSource.

The ES entity ‘s’ is visible across the form.

If the user selects another row in the grid, we need to detect if they have made any changes to the current record, and save it.

private void askSave()
{
    if (s.es.IsDirty)
    {
        DialogResult result = MessageBox.Show("Save changes?", "ES Test App", 
MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) { s.Save(); this.surveys.LoadAll(); this.advancedList1.DataSource = this.surveys; this.advancedList1.Refresh(); } } }

The 1st thing the askSave method does is to determine if the data has been altered using the property of the underlying entity. if (s.es.IsDirty)

Having determined it is, and that the user indeed wants to save it, it’s a simple matter to call the Save() method on the entity itself. After which, a call to reload the surveys collection and a refresh of the AdvancedList grid is all that’s required.


Adding a new record

Adding a new record is easy, too. I have an event attached to an AddNew menu item that looks like this.

private void AddNew_Click(object sender, EventArgs e)
{
    Survey s = new Survey();
    s.AddNew();
    showDetails((Guid)s.Id);
}

The ES AddNew() method is called to create a new entity and the Guid is passed to showDetails() to display it for editing.

Note: The AddNew() method is overloaded in the Custom Class to generate the Guid immediately rather than relying on the default mechanism in the database.

public partial class Survey : esSurvey
{
    public override void AddNew()
    {
        base.AddNew();
        this.Id = Guid.NewGuid();
    }
}

Conclusion

And... there you have it; a VS WM5 solution, an SQL Ce database, some easily generated ES BusinessObjects, a couple of Resco controls, and a few lines of code, all blended into a working application. After you've done it once, you can probably do your next project in less time than it took you to read this. Enjoy! 


 

Robert CampbellRobert Campbell was educated in Newcastle Upon Tyne University in Agricultural Engineering, worked in manufacturing for 15 years before moving into IT in the mid 80's, and worked for a variety of consulting organizations before setting up ecommnet in 1998 at the start of the dot.com boom to specialize in security and web based applications development. ecommnet is now specializing in mobile applications development and security, Web 2.0 and identity management. ecommnet are NOKIA Enterprise Solutions Certified Mobility Partners.

ecommnet ltd., Bewick House, Horsley Business Centre, Horsley, Newcastle Upon Tyne, NE15 0NY
DDI: +44 8451-740-633, T:+44 1661 854 492 F :+44 1661 854 632 M:+44 7801 270 264

posted on Tuesday, May 15, 2007 5:17:08 PM (Eastern Standard Time, UTC-05:00)  #   
 Sunday, November 19, 2006

The EntitySpaces 1.5.2 Bets is now available for download. Below are the enhancements and fixes added to this release:

  • Full support for VistaDb 3.0
  • Compact Framework Providers for both Microsoft SQL Server and VistaDb
  • Full compliance with the DotNetNuke {objectQualifier} when using dynamic sql or stored procedures.
  • EntitySpaces can now be run without a config file. This is intended to help facilitate modular software development, and removes the situation where your end users are required to enter config entries. Below is an example of how to set your default connection programmatically


// Manually register a connection
esConnectionElement conn = new esConnectionElement();
conn.ConnectionString = "User ID=sa;Password=;Initial Catalog=Northwind;Data Source=localhost";
conn.Name = "GroovySQL";
conn.Provider = "EntitySpaces.SqlClientProvider";
conn.ProviderClass = "DataProvider";
conn.SqlAccessType = esSqlAccessType.DynamicSQL;
conn.ProviderMetadataKey = "esDefault";conn.DatabaseVersion = "2005";

// Assign the Default Connection
esConfigSettings.ConnectionInfo.Connections.Add(conn);
esConfigSettings.ConnectionInfo.Default = "GroovySQL";

// Use the code as usual
Employees e = new Employees();
if (e.LoadByPrimaryKey(1))
{
    e.Save();
}

int? i = e.EmployeeID;

  • Added [XmlIgnore] to hierarchical objects to prevent endless loops with self referencing relationships. This will be further refined again in our 1.6.0 release.
  • Added Lock/SyncLock in two places to protect static data

This is a full beta and all providers are included.

  1. This beta requires the new MyGeneration beta available on the MyGeneration homepage.
  2. The EntitySpaces beta can be found in the trial forum HERE
posted on Sunday, November 19, 2006 9:20:55 AM (Eastern Standard Time, UTC-05:00)  #   
 Friday, August 04, 2006

We have released the first beta version of our EntitySpaces DotNetNuke ASCX Admin Grid Template Suite. Check out the demo here.

Here is an overview of the features:

  • All of the databases supported by EntitySpaces should work with these templates
  • The ASCX controls generated build upon your already created EntitySpaces Classes
  • Both C# and VB.NET ASCX controls can be generated*
  • The look and feel of the ASCX controls are managed by a very simple style sheet
  • The generated ASCX controls use the new ASP.NET MultiView/View controls
  • Browse, Detail, Edit, and Search modes can be generated automatically
  • You control what columns to display and in what order
  • All column headers are clickable and sort the GridView(s)
  • Required fields use the ASP.NET RequiredFieldValidator control
  • Foreign Keys are mapped to Url's in detail mode and combo-boxes in edit mode
  • Relationships can be mapped to subgrids in detail mode

*During the beta period there will only be a C# version. After user testing, if no issues arrise we will create the VB version. Both Versions will be available to all customers.

Files

The template is installed into the EntitySpaces\C#\Web and EntitySpaces\VB\Web folders respectively in MyGeneration. GridLoader.zip the DotNetNuke module that loads the generated ASCX controls is installed in Program Files\EntitySpaces\DotNetNuke\C# and Program Files\EntitySpaces\DotNetNuke\VB respectively.

Usage

  1. Add the needed EntitySpaces assemblies, and web.config entries to your DotNetNuke portal. For detailed instructions on how to do this see here.
  2. Install the GridLoader.zip DotNetNuke module like you would any other. Because we are using the new dynamic compilation model of ASP.NET 2.0 you must also add the directoryName key to the codeSubDirectorySection of your web.config as seen below(this is only necessary if you are using the C# version). You will see a commented out example in the appropriate location of your web.config if you have never done this before.

    <codeSubDirectories>
         <add DirectoryName="GridLoader" />
    </codeSubDirectories>

  3. Generate your EntitySpaces classes for your tables/views just like normal and upload them to /App_Code/GridLoader/Custom and /App_Code/GridLoader/Generated
  4. Generate your ASCX controls and upload them to /DesktopModules/GridLoader/
  5. Think about how easy EntitySpaces makes your life and have a beer.

You will find a new installer for this template suite on the downloads page under the products menu entry. This template suite will not be lincluded in the trial version of EntitySpaces. These templates are intended to provide the ability to administer databases over the web from within your DotNetNuke portal. This chore is typically overlooked although it is really very needed. Such admin screens can eat up quite a bit of development time and they are much easier to generate, and change when your database schema does. The demo module on our site is 100% generated no hand coding was done.

These templates are not currently supported on the same level as the templates that generate the EntitySpaces classes. Work on the new features in the upcoming 1.5 release will take priority. That being said we will of course address an issues that might arise as time allows.

See the PDF file that describes the usage of ASPX version of the template. All functionality and operations are exactly the same for the DotNetNuke ASCX version, with the exception of the "Use Master Pages"option.

posted on Friday, August 04, 2006 12:43:23 PM (Eastern Standard Time, UTC-05:00)  #   
 Tuesday, May 23, 2006

We just posted a video here to illustrate how simple it is to use EntitySpaces for module development on the DotNetNuke 4.x platform. This gets you up to where our standard code generation video starts with generating your EntitySpaces objects. We do plan to post an additional code generation video specifically for DotNetNuke in the near future, so stay tuned.

posted on Tuesday, May 23, 2006 7:06:40 PM (Eastern Standard Time, UTC-05:00)  #   
 Saturday, May 13, 2006

 

EntitySpaces 1.4 initially was targeted for May 31st, however, we had to make some adjustments. Hierarchical support is now the main focus of our next release (1.5). Also, the ASPX templates are still underway and will be released separately before the 1.5 release. We had also planned on doing some databinding work as well but that has been pushed to 1.5 as well. However, all that said this is a terrific release, we have some very good features, a few fixes, and even a new MySQL provider in 1.4. See the release notes below for the details.         


·          EntitySpaces 1.4

o         Added templates to provide full VB.NET support

§          Includes a full set of Custom, Generated, and MetadataMap templates.

§          It is no longer necessary to pre-compile the generated code under C#.

§          Note: If you are using VBExpress, we recommend opening your Project Properties, selecting the Application properties tab, and clearing the Root namespace that the IDE set by default. That way, when you add “Imports BusinessObjects” to your code, it will work as expected.

o         Added an EntitySpaces provider for MySQL.

§          Works with MySQL 4.x using DynamicSql mode.

§          Works with MySQL 5.x and supports both DynamicSql and StoredProcedure modes, as well as Views.

o         Added an EntitySpaces Template to produce MySQL 5.x stored procedures.

o         Fixed stored procedure parameter name prefix handling for SQL Server, Oracle and Access.

o         Fixed parameter name handling for column names with spaces.

o         Added output parameter support to esParameters.         

public string GetFullName(int employeeID)
{
   
esParameters parms = new esParameters();

   
parms.Add("EmployeeID", employeeID);
   
parms.Add("FullName", esParameterDirection.Output, DbType.String, 40);

   this.ExecuteNonExec(esQueryType.StoredProcedure, "proc_GetEmployeeFullName", parms);

   return parms["FullName"].Value as string;
}

o         Fixed an obscure bug in Transaction Manager. (Special thanx to Graham Scragg and Thomas Coats for working with us on this.)

o         Improved Exception handling. We no longer wrap the exceptions which will make it much easier for you to see the real exception.

o         Updated and improved compiled help.

 

 

·          DotNetNuke

o         Includes an EntitySpaces ControlPanel module for DotNetNuke.

§          Displays EntitySpaces assembly information.

§          Allows you to upload/update EntitySpaces assemblies.

§          Allows you to encrypt/decrypt connection information in config files.

o         Added new template to create Sql scripts for DotNetNuke module development.


 

·          ASP.NET

o         Includes ASP.NET code for an EntitySpaces ControlPanel.

§          Displays EntitySpaces assembly information.

§          Allows you to update EntitySpaces assemblies.

§          Allows you to encrypt/decrypt connection information in config files.


 

·          EntitySpaces SqlDemo

o         Includes code demonstrating encrypting/decrypting app.config connection information.

o         Note: If SqlDemo is run from within Visual Studio, SqlDemo.vshost.exe.config gets encrypted. This file is only used by Visual Studio and should never be distributed with your application. To encrypt SqlDemo.exe.config, run SqlDemo.exe directly from the bin\Debug folder.


 

·          EntitySpaces Test Suite

o         Updated the test fixtures and added NUnit projects to test the EntitySpaces provider for MySQL.

o         Duplicated the C# tests in VB.

Note: Installation instructions at the bottom of the Release Notes for 1.4 contain special instructions for MySQL users. They explain how add the required Language Mapping to MyGeneration.


posted on Saturday, May 13, 2006 11:49:34 AM (Eastern Standard Time, UTC-05:00)  #   
 Thursday, May 11, 2006

Wow, so many good things to talk about for the upcoming EntitySpaces 1.4 drop. Another addition, is a complete template to generate DotNetNuke ready install scripts for any of your EntitySpaces business objects. It works just like any of our other stored procedure templates, and will allow you to generate a DNN ready script for all of your tables/stored procedures in one fell swoop. We previously mentioned that we will also be releasing native vb.net templates for ES with 1.4, so what are you waiting for DotNetNuke module developers? Quit wasting your time writing buggy, un-tested object persistence code and do it the easy way. ES 1.4 is scheduled to hit on Monday 05/15, get ready.

posted on Thursday, May 11, 2006 9:31:07 AM (Eastern Standard Time, UTC-05:00)  #