Tuesday, July 28, 2009

This little gem was brought up by one of our customers, Paul_IBSoftware, and it looked like fun to implement so we snuck it into our Q3 release. Nothing like getting a suggestion and having it in the product the same day. Basically, we had the SQL conjuctions AND and OR but we didn’t have anyway to indicate AND NOT or OR NOT but that is no longer true, see the example below.

VB.NET

Dim q As New EmployeesQuery()
q.es.Top = 1
q.Where(q.EmployeeID = 1 And Not (q.LastName = "goofy"))
q.Load()

Notice you can now use And Not/Or Not in your query syntax. This will yield the following SQL syntax.

SELECT  TOP 1 *
FROM [Employees]
WHERE ([EmployeeID] = @EmployeeID1 AND NOT [LastName] = @LastName2)

C#

You can do this in C# too, however this is one case where the VB.NET syntax reads better than the C# syntax. Take a look at the sample below.

EmployeesQuery q = new EmployeesQuery();
q.es.Top = 1;
q.Where(q.EmployeeID == 1 && ! (q.LastName == "googy"));
q.Load();

Granted, a C# developer would probably never think of that syntax, but it yields the exact same SQL as above. Probably a C# developer would write it as below

EmployeesQuery q = new EmployeesQuery();
q.es.Top = 1;
q.Where(q.EmployeeID == 1 && (q.LastName != "googy"));
q.Load();

The above query would product the following SQL.

SELECT  TOP 1 *
FROM [Employees]
WHERE ([EmployeeID] = @EmployeeID1 AND [LastName] <> @LastName2)

Summary

The EntitySpaces 2009 Q3 DynamicQuery is going to blow your socks off. We are so excited about this release, things are moving very quickly too.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Silverlight application, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Tuesday, July 28, 2009 6:31:17 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Monday, July 27, 2009
kick it on DotNetKicks.com

We have our Sybase SQL Anywhere implementation working quite well now. We are releasing a new alpha on August 3rd that will come with a new provider for Sybase SQL Anywhere including a Compact Framework provider as well for Sybase mobile development. We have been developing and testing with SQL Anywhere version 11. Everything is working great including autoincrement keys, concurrency checking, and so on. We haven't tested our stored procedures yet but should have that work completed by August 3rd. Remember Sybase fans, EntitySpaces runs under Mono as well.

Having never really used Sybase before we must say it really is a very full featured database and they have worked with us very well. We basically have a red phone we can pick up and get right to technical support, fantastic! Sybase really seems to be focused on customer service more so than most companies we’ve worked with, maybe that’s part of why Sybase has announced terrific earnings for Q2 of this year, who else can say that? We will be taking a look at supporting their Ultra Light version as well. Sybase is a very serious contender in the database world, you will be hearing more from us on this subject in the future. If you don’t know much about Sybase click on some of the links in this post, we think you will be impressed.

This should be our last Alpha version. Soon we will be upgrading all our providers to support the new features we've implemented (with some still yet to be added). We will then provide a beta release that will be made available to the general public as a trial version as we head down the home stretch for EntitySpaces 2009 Q3.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Silverlight application, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Monday, July 27, 2009 9:43:51 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Tuesday, July 21, 2009

We thought we would use this blog post to report more progress on our EntitySpaces 2009 Q3 release. However, before we continue we want to point out that our current production release is EntitySpaces Q1 2009.1.0209.0 and it is available now, it is also very stable (as usual). Okay, so here is some of the new functionality, we are working through our Q3 Wish List forum posts.

image

In the above image we have selected the EntitySpaces 2009 Metadata tab. We have highlighted two areas in the image for purposes of this post. The red box is a .NET PropertyGrid control and we use this now instead of what we used to use, which was a .NET DataGrid. Not only does it look better and allow us to group data by functionality, but it also allows for easy editing. The blue box highlights certain fields that you can edit directly in the metadata. Notice that you can edit the “Alias” directly in the Metadata. Also, there is an Exclude flag which you can set to true to indicate that you want this column skipped entirely during code generation purposes. There is also a new flag called IsUniversalConcurrency which you can set on any integer type field (I can see econner jumping for joy already!). This will allow you to have exact matching schema’s across multiple databases and still have concurrency checking. The reason this is needed is Microsoft SQL’s Timestamp for instance is not really compatible with other database systems, or said better there really is no universal concurrency checking built into dbms systems so we will provide one for you. Finally, we have IsCustomAutoKey and CustomAutoKeyText, these will replace the current way that Oracle users (and possibly others) have to provide key/value pairs in our user metadata. We will automatically convert your current UserData.xml files for you to support his new approach. All of our Metadata is now presented this way (not just column information).

What is nice about this new approach is that we can expand it easily in the future and behind the scenes any values that you edit end up in the user metadata just as it would if you were typing in key/value pairs only it’s so much easier. We are also considering making IsInPrimaryKey editable so that you can make tables without primary keys appear as though they had them.

Also, we have eliminated the problem that prevented you from daisy chaining queries when joins were involved.

We have also flushed out the DynamicQuery API such that you have no operator precedence issues, for instance.

query.Where(42 > query.Age);

or

query.Where(query.Age < 42);

The same holds true with our mathematical operators as well.

query.Select(“Wow” + query.FirstName + “Cool”); // notice the string “Wow” comes first

or

query.Select(100 * query.Age);  // Notice the 100 comes first

Progress is moving very rapidly and we are still passing at 100% in our unit tests (including a bunch of new tests that have been added).

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Silverlight application, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Tuesday, July 21, 2009 6:42:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Thursday, July 16, 2009
kick it on DotNetKicks.com

We have pushed our EntitySpaces Silverlight application up so you can run it and take a look at it. We decided to compile it under the Silverlight 3 toolset so it requires Silverlight 3 to run it. We did this to make sure we are compatible. Silverlight 3 is RTM now and you can download the Visual Studio tools for it HERE but you do not need these to run the demo, just to develop Silverlight 3 applications. There is a lot of code posted in this blog post but we thought you might really want to know how this stuff works, it’s not that hard to understand if you take the time to look at the code. The online demo can be found here ==> DEMO

image

You can add rows and edit rows and then save the data. We are using the Microsoft SQL Northwind database, specifically the Employees table. When you search you can search on the first name or last name fields. The purpose of this demo is not to make a really cool Silverlight UI, but to show how easy it is to use EntitySpaces to write a Silverlight application. There is one glitch when editing data. You need to move off of the selected row for your edits to “take”. This is a Silverlight issue and not an EntitySpaces Issue. The demo is included in our current alpha, however the version shown here is fancier. (It will be in the next release as shown above).

The EntitySpaces Silverlight Demo uses our EntitySpaces proxies on both sides of the conversation. The client side proxies run under Silverlight and our server side proxies run on the server. The Silverlight application hits our WCF service to fetch the data.

The WCF Service

This is what the WCF Service looks like including the Interface. The Interface for the service is shown below. Notice we are returning and taking the EntitySpaces Proxy Stub classes as parameters. However, we pass the EntitySpaces DynamicQuery to the server in string form. The EntitySpaces DynamicQuery is now fully functional under Silverlight and requires only a single 49k assembly which will automatically download with your Siverlight application.

using System.ServiceModel;
 
using BusinessObjects;
 
namespace EntitySpaces.SilverlightApplication.Web
{
    [ServiceContract]
    public interface INorthwind
    {
        [OperationContract]
        EmployeesCollectionProxyStub GetEmployees(string employeesQuery);
 
        [OperationContract]
        EmployeesCollectionProxyStub SaveEmployees(EmployeesCollectionProxyStub collection);
    }
}
 
The implementation class is shown below. Notice in GetEmployees() we deserialize the incoming query (passed as a string) with a single one-line call into a full server side query that we can execute. We then use that query to load our collection, and finally wrap it with a proxy collection and return it. The Save() method is ridiculously simple and powerful. Notice that we merely access the incoming proxies “Collection” property (which is a full EmployeesCollection class) and call save on it. Then we simply return the very same proxy that was sent to us as the incoming parameter. Try clicking the Add button in our demo a few times and then press the Save button. Notice the auto identity columns are immediately reflected in the grid. These are returned automatically via our save method. This is an incredibly powerful and easy way to create Silverlight applications. The row state, including added, modified, and deleted, are automatically maintained for you. All you have to do is call save.
 
using System;
using System.Collections.Generic;
using System.ServiceModel.Activation;
 
using BusinessObjects;
 
namespace EntitySpaces.SilverlightApplication.Web
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Northwind : INorthwind
    {
        #region INorthwind Members
 
        public EmployeesCollectionProxyStub GetEmployees(string serializedQuery)
        {
            List<Type> types = new List<Type>();
            types.Add(typeof(EmployeesQuery));
 
            EmployeesQuery employeesQuery = EmployeesQuery.SerializeHelper.FromXml(
                serializedQuery, typeof(EmployeesQuery), types) as EmployeesQuery;
 
            EmployeesCollection employeesCollection = new EmployeesCollection();
            if (employeesCollection.Load(employeesQuery))
            {
                EmployeesCollectionProxyStub proxy = new EmployeesCollectionProxyStub(employeesCollection);
                return proxy;
            }
 
            return null;
        }
 
        public EmployeesCollectionProxyStub SaveEmployees(EmployeesCollectionProxyStub collection)
        {
            if (collection != null)
            {
                collection.GetCollection().Save();
                return collection;
            }
 
            return null;
        }
 
        #endregion
    }
}


The Silverlight Page

Our Page.xaml file looks like this. A lot of this is just noise like setting up the buttons and such. The part you are interested in is the <data:DataGrid.Columns> section where we manually setup the columns we want to display in the grid. We could have used AutoGenerateColumns=“True” however. For the two date columns we use a DataGridTemplateColumn in order to hookup the fancy date editing control. We also set the EmployeeID column to read only so that users cannot edit the primary key.

<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="EntitySpaces.SilverlightApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Grid Background="Black" >
 
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>
 
        <Grid Grid.Row="0" Margin="7">
 
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"></ColumnDefinition>
                <ColumnDefinition Width="300"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="240"></ColumnDefinition>
                <ColumnDefinition Width="75"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            
            <HyperlinkButton Grid.Column="0" NavigateUri="http://www.entityspaces.net" TargetName="New"><Image Source="EntitySpaces_Logo.jpg" Grid.Column="0" /></HyperlinkButton>
            <TextBlock Name="SearchTextBlock" Grid.Column ="1" Text="EntitySpaces 2009 Silverlight Demo" Foreground="Yellow" FontSize="14" Margin="10,5,10,5" VerticalAlignment="Center"></TextBlock>
            <ProgressBar Name="WorkingBar" Grid.Column="2" Foreground="Yellow" Background="Black" Value="0" Maximum="100" Margin="2,2,2,2" />
            <TextBox Name="SearchTextBox" Text="Enter Criteria Here" Grid.Column="3" Margin="20,0,20,0" Padding="10,5,10,5" FontSize="14" GotFocus="SearchTextBox_GotFocus"></TextBox>
            <Button Name="SearchButton" Content="Search" Grid.Column="4" FontSize="14" Click="SearchButton_Click"></Button>
        </Grid>
 
 
 
        <Grid Grid.Row="1" Margin="7">
            <data:DataGrid Name="EmployeesDataGrid" AutoGenerateColumns="False" >
 
                <data:DataGrid.Columns>
 
                    <data:DataGridTextColumn Binding="{Binding EmployeeID}" Header="Employee ID" IsReadOnly="True" />
                    <data:DataGridTextColumn Binding="{Binding FirstName}" Header="First Name" />
                    <data:DataGridTextColumn Binding="{Binding LastName}" Header="Last Name" />
                    <data:DataGridTextColumn Binding="{Binding HomePhone}" Header="Home Phone" />
                    <data:DataGridTextColumn Binding="{Binding City}" Header="City" />
 
                    <data:DataGridTemplateColumn Header="Hire Date" Width="160">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding HireDate, Mode=OneWay, Converter={StaticResource ShortDateConverter}}" VerticalAlignment="Center" Margin="2"/>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                        <data:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <controls:DatePicker SelectedDate="{Binding HireDate, Mode=TwoWay}" />
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellEditingTemplate>
                    </data:DataGridTemplateColumn>
 
 
                    <data:DataGridTemplateColumn Header="Birth Date" Width="160">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding BirthDate, Mode=OneWay, Converter={StaticResource ShortDateConverter}}" VerticalAlignment="Center" Margin="2"/>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                        <data:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <controls:DatePicker SelectedDate="{Binding BirthDate, Mode=TwoWay}" />
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellEditingTemplate>
                    </data:DataGridTemplateColumn>
 
                </data:DataGrid.Columns>
 
            </data:DataGrid>
        </Grid>
 
        <Grid Grid.Row="2" Margin="7">
 
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="75"></ColumnDefinition>
                <ColumnDefinition Width="15"></ColumnDefinition>
                <ColumnDefinition Width="75"></ColumnDefinition>
                <ColumnDefinition Width="15"></ColumnDefinition>
                <ColumnDefinition Width="75"></ColumnDefinition>
            </Grid.ColumnDefinitions>
 
            <Button Name="AddButton" Content="Add" Grid.Row="2" Grid.Column="1" FontSize="14" Click="AddButton_Click" ></Button>
            <Button Name="SaveButton" Content="Save" Grid.Row="2" Grid.Column="3" FontSize="14" Click="SaveButton_Click" ></Button>
            <Button Name="ClearButton" Content="Clear" Grid.Row="2" Grid.Column="5" FontSize="14" Click="ClearButton_Click" ></Button>
        </Grid>
 
    </Grid>
</UserControl>

 

Our Page.xaml.cs file is shown below. Take a look at the SearchButton_Click event. We build the EntitySpaces DynamicQuery and call the service.GetEmployeesAsync() method passing in the query in string form. In the service_GetEmployeesCompleted() method we access our EmployeesCollectionProxyStub class which was returned to us in the “e.Result” variable. However, now we are working with the client side lightweight proxy class. The interesting thing about this approach is that we are NOT using the Visual Studio generated proxies. Our proxies are smart and maintain row state, and they are going to get even smarter. This approach makes EntitySpaces a terrific architecture for building your Silverlight applications. The SaveButton_Click is also incredibly simple. The timer stuff you see is just to make the fancy progress bar work in the demo.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
 
using EntitySpaces.SilverlightApplication.NorthwindClient;
using Proxies;
 
 
namespace EntitySpaces.SilverlightApplication
{
    public partial class Page : UserControl
    {
        private NorthwindClient.NorthwindClient service = new NorthwindClient.NorthwindClient();
        private Proxies.EmployeesCollectionProxyStub employees;
        private Storyboard Timer = new Storyboard();
        private int RecordsAdded;
 
 
        public Page()
        {
            InitializeComponent();
            Timer.Completed += new EventHandler(Timer_Completed);
            Timer.Duration = TimeSpan.FromMilliseconds(2);
        }
 
        private void SearchButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Proxies.EmployeesQueryProxyStub q = new Proxies.EmployeesQueryProxyStub("emp");
 
                q.Select(q.EmployeeID, q.FirstName, q.LastName, q.HomePhone, q.HireDate, q.BirthDate, q.City);
                q.Where(
                    q.FirstName.Like("%" + SearchTextBox.Text + "%") |
                    q.LastName.Like("%" + SearchTextBox.Text + "%"));
                q.OrderBy(q.LastName.Ascending);
 
                service.GetEmployeesCompleted += new EventHandler<GetEmployeesCompletedEventArgs>(service_GetEmployeesCompleted);
                service.GetEmployeesAsync(Proxies.EmployeesQueryProxyStub.SerializeHelper.ToXml(q));
 
                WorkingBar.Value = 0;
                Timer.Begin();
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.StackTrace);
            }
        }
 
        void service_GetEmployeesCompleted(object sender, GetEmployeesCompletedEventArgs e)
        {
            WorkingBar.Value = 100;
            Timer.Stop();
            
            if (e.Result != null)
            {
                employees = e.Result;
                EmployeesDataGrid.ItemsSource = employees.Collection;
            }
        }
 
        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            SearchTextBox.Text = "";
            employees = null;
            EmployeesDataGrid.ItemsSource = null;
        }
 
        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (employees == null) return;
 
                WorkingBar.Value = 0;
                Timer.Begin();
 
                service.SaveEmployeesCompleted += new EventHandler<SaveEmployeesCompletedEventArgs>(service_SaveEmployeesCompleted);
                service.SaveEmployeesAsync(employees);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.StackTrace);
            }
        }
 
        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            if (employees == null)
            {
                employees = new EmployeesCollectionProxyStub();
                EmployeesDataGrid.ItemsSource = employees.Collection;
            }
 
            if (RecordsAdded++ < 5)
            {
                EmployeesProxyStub newEmp = new EmployeesProxyStub();
                newEmp.FirstName = "Scott";
                newEmp.LastName = "Schecter";
 
                employees.Collection.Add(newEmp);
            }
        }
 
        void service_SaveEmployeesCompleted(object sender, SaveEmployeesCompletedEventArgs e)
        {
            try
            {
                WorkingBar.Value = 100;
                Timer.Stop();
 
                RecordsAdded = 0;
 
                employees = e.Result;
                EmployeesDataGrid.ItemsSource = employees.Collection;
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.StackTrace);
            }
        }
 
        private void SearchTextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            if (SearchTextBox.Text == "Enter Criteria Here")
            {
                SearchTextBox.Text = "";
            }
        }
 
        void Timer_Completed(object sender, EventArgs e)
        {
            WorkingBar.Value++;
            Timer.Begin();
 
            if (WorkingBar.Value > 100)
            {
                WorkingBar.Value = 1;
            }
        }
    }
}

Rather than repeat of bunch of content from previous posts, here are two posts that will help you further understand how we created the entire solution.

1) How we generated the lightweight client side proxies.

2) How we built the application and informed Visual Studio to use our proxies rather than generate proxies for us.

Be sure when you execute the “Generated Master” template to check the “Serializable Queries” checkbox on the advanced tab. Again, the demo is included in the latest alpha. We are even adding a new checkbox that will “scrunch” the XML when it goes over the wire so that your packets are much smaller. The XML will send all of your fields as “a1”, “a2”, “a3” and so on rather than “EmployeeID”, “FirstName”, “LastName”. This will make a big difference when sending large chunks of data from client to server and back again. Of course, we only send the columns that actually have data (non null/default) so your XML will be very tiny. This will not impact your proxies, they of course will still have your nice property names.

Well, that’s it for now. We are not only working on Silverlight and Proxies, we are also working through the Q3 Wish List as well.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Silverlight application, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Thursday, July 16, 2009 10:42:46 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, July 12, 2009

The Developer version and Source version have been published for this release. You must uninstall any prior versions of EntitySpaces 2009 including the production release or any prior alphas. EDIT – 2009-08-07: This Alpha only supports the EntitySpaces provider for SQL Server.

These are new features contained in this release:

  • The EntitySpaces Hierarchical Object Model Improvements
  • The EntitySpaces 2009 Getting Started PDF is now on the EntitySpaces 2009 menu after installation.
  • You can turn off the DateTime value in your class headers so that they wont cause differences in your source control system (in the settings tab).
  • Major Improvements to our lightweight client side proxies.
  • Our Silverlight demo which demonstrates using our proxies on both sides of the Silverlight / WCF conversation complete with editing and saving data through a grid. We will be posting the demo online so you can execute it and play with it. You will find it on our Samples menu after install it will compile right out of the box, just see the Readme.txt file in the solution.

Lightweight Client Side Proxy Stub – Major Improvements

The lightweight client side proxies now support

  • The INotifyPropertyChanged interface
  • ObservableCollections (great for Silverlight support)
  • And a Silverlight checkbox will we remove any non supported items such as [Serialized] attributes

image

We used the settings above settings to create the client side proxies for our Silverlight demo. Below is what our proxy collection looks like.

image

Noitce the Collection property is an ObservableCollection. In our Silverlight demo you can add records directly to your collection and they will automatically show up in the grid.

image

Above is our single Entity object. It implements the INotifyPropertyChanged interface. You can change a property directly on your Entity object it will immediately be reflected in the Silverlight grid.

We are adding a lot of enhancements to our lightweight client side proxies. You can begin your Silverlight application starting with this Alpha, it is working very well. A few things will be adding are a compressed mode where we will “Scrunch” the XML being sent over the wire by giving your property names in XML like “a1, a2, a3, a4, a5 …” and so on to reduce the size of the XML packet. This isn’t really an EntitySpaces issues its just the result of XML itself which is pretty bulky and will not effect your code in any way.

We will be hosting our new EntitySpaces Silverlight demo on our site and providing some insight on how it all operates. It is very simple to create Silverlight applications with EntitySpaces 2009 and the full demo is including with this latest alpha. The demo runs against Microsoft SQL’s Northwind database.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Sunday, July 12, 2009 2:46:59 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, July 11, 2009

The “Selected Tables Only” checkbox

We have implemented a long standing request that provides you with more control over how your hierarchical object model is created. Now you can limit your hierarchical object model to include only those tables that you have selected at code generation time. When EntitySpaces creates your hierarchical object model it does so using your foreign keys in your database to determine the relationships. Let’s take a look at how this new “Selected Tables Only” checkbox logic works.

image image

Notice above that we have checked the “Selected Tables Only” checkbox and that we have only two tables selected (the “Employees” and the “Orders” table). When EntitySpaces generates the code it will generate the Employees and Orders classes as usual. However, since we have checked the “Selected Tables Only” checkbox only the hierarchical properties involving the Orders and Employees table will be added as hierarchical properties. Let’s take a look at the Employees class (below) generated with the above settings and see what it looks like.

image

Notice the Employees class contains only the self referencing ReportsTo properties and the OrdersCollectionByEmployeeID property. This is because only these two tables were selected and of course we checked the “Selected Tables Only” checkbox.

image

The Orders class above contains only the Employee hierarchical property for the same reason.

Without the “Selected Tables Only” checkbox

Finally, let’s regenerate with the “Selected Tables Only” un-checkbox and show you what the difference would be. When you leave the “Selected Tables Only” checkbox un-checked the hierarchical object model will include all of the related objects regardless of what tables you have selected (this is currently how it works).

image

The Orders table hierarchical properties would be as follows.

image

This feature is already implemented and will be included in our next release and is one of the items requested in our Q3 Wish list forum. This can come in real handy when your database contains many tables and you only want a subset of them in your hierarchical object model. This can also be very useful in DotNetNuke development if you wanted to include the users and roles tables only for instance and not have to include all of the other tables they reference (due to the hierarchical properties). We are working through the Q3 Wish list and implementing the requests quite rapidly.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Saturday, July 11, 2009 7:51:01 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Thursday, July 09, 2009
image

When we moved from ES2008 to ES2009 we didn’t update our Getting Started PDF, however, that has now been rectified. This document can be of great help to those just downloading EntitySpaces or even those who have been customers for some time and want to know more about all of the options on the Advanced Tabs for instance. This document is up-to-date with our current Alpha as well. The Getting Started PDF is available on our home page under the “Documentation” menu and will be included in all future releases and available under your “EntitySpaces 2009” menu after installation.

You can download and view the documentation by clicking on the link below.
http://www.entityspaces.net/documentation/GetStarted.pdf

Of course as always your feedback is welcome.


From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Silverlight application, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Thursday, July 09, 2009 10:49:27 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Wednesday, July 08, 2009
kick it on DotNetKicks.com

Okay, we finally got it!! We can honestly say getting a grip on Silverlight has been a real learning curve for our team, but it’s going to be a breeze for EntitySpaces customers because we’ve done all the research and laid all of the track. Our first approach was to use strings for everything because we didn’t want to use the “brain dead” proxies created by Visual Studio when you add a service reference to a Silverlight project. Then we figured out how we could force Visual Studio to use our client side proxies when adding a service reference. This is truly awesome. I cannot imagine a better way to write Silverlight applications than with EntitySpaces. What we are about to show you is so easy it will floor you. We will also be making a video on this and making our demo available with a future alpha or beta version. Okay, enough hype, show us already !!

image

Above, is our Silverlight Solution that contains everything needed to run the entire demo. Notice first, that we have all of the EntitySpaces runtime projects included rather than just references to the dlls (EntitySpace.Core35, etc.). We do this as we develop so we can debug and fix things if need be. Naturally, these project references are not required in your solution. You only need to add the runtime dll references to the project which houses your WCF service, EntitySpaces.SilverlightApplication.Web in this case.

Also notice the first project in the red box, EntitySpaces.Proxies.Silverlight. This is simply a Silverlight class library that we added to our solution. Then we generated our client side proxies into that solution. So now we have our client side proxies housed in a Silverlight class library. We could have just added these to our SilverlightApplication but there is a very important reason we didn’t. More on this later. These are generated via our Client Side Proxy Stub Template.

Next we have the SilverlightApplication project itself. This is the Silverlight application that runs in the browser. It references our EntitySpaces.Proxies.Silverlight class library that houses our client side proxies, and it references the EntitySpaces.DynamicQuery.Silverlight assembly because we want to be able to run full “es” DynamicQueries under Silverlight. Of course this project also contains our Page.xaml.cs file which contains our code that executes everything under Silverlight, we’ll be looking at that in a moment.

Finally, we have our EntitySpaces.SilverlightApplication.Web project which houses our WCF service in a web application. The two important files we’ll be looking at here are the INorthwind.cs file and the Northwind.svc.cs file.

Let’s start with the WCF Service

image

We have two methods. GetEmployees takes a serialized query in string form (the only time we have to use strings is with a query) and returns the data through our server side proxy class “EmployeesCollectionProxyStub”. Our Save method takes and returns a server side “EmployeesCollectionProxyStub” as well. The server side proxy stubs are generated via the Generated Master template. You indicate that you want them created via the Proxy/Stub tab as shown below. Also, be sure and check the “Serializable Queries” checkbox on the advanced tab.

image 

 

You can see how simple our WCF Service is in this example. Let’s look at the Northwind.svc.cs file.

image

First, look at the second method, our SaveEmployees() method. Could this be any easier? Not only do you not have to worry about which rows are added, modified, or deleted, but you can simply call Save, and return the very same collection. All new records, including their identity columns and such, will be returned to the Silverlight application so it can update it’s grid (in our case).

The GetEmployees method is a little more complicated, but not by much. It merely deserializes the string (a serialized proxy query) into a full blown EmployeesQuery, asks the EmployeesCollection to load it, then creates an EmployeesCollectionProxyStub class, passing in the EmployeesCollection, and returns it. Pretty simple really.

The Silverlight Application Logic

Let’s take a look at what our Silverlight Application looks like.

image

What the demo application does is create an EntitySpaces DynamicQuery when the user clicks on the Search button, calls our WCF service method GetEmployees(), then populates the grid with the data. The user can edit the data in the grid, and then merely click the Save button, which calls the WCF service method SaveEmployees(). Again, pretty simple.

So let’s look at our page.xaml.cs file. (We’ve removed any error handling to make the screen shot smaller.)

image

Notice in SearchButton_Click we create a EmployeesQueryProxyStub and use it exactly as we do with our full server side DynamicQuery objects, only we cannot load it directly. It must be serialized and sent to the server. In the last line of that method, we call our WCF service method GetEmployees().

In service_GetEmployeesCompleted() we assign e.Result to “employees”, which is our client side EmployeesCollectionProxyStub object, then we bind to employees.Collection, and our grid is populated.

Now, in the save button click event we intentionally set the first rows’ name to “GoogyGaga”, then add an additional Employee just for kicks, and call our WCF service method SaveEmployees(), which returns a refreshed collection, which we again assign to “employees”, and rebind the grid.

That’s it folks. An entire Silverlight application using EntitySpaces, showing both sides of the conversation. EntitiySpaces not only provides the glue between Silverlight and WCF, but it also provides all of the database access as well. All generated in mere seconds from your database schema via our Visual Studio Add in. Does it get any better than this?

Making Visual Studio Use the EntitySpaces Proxies instead of Visual Studio Generated Proxies

This is very cool indeed. We do not want to use Visual Studio generated proxy classes because they do not maintain row state for us (and other things). Our client side proxies maintain what rows are modified, added, and deleted such that you can send the entire collection back to the server and simply call Save() on it and bingo, it’s in the database. Here’s the trick. Remember the EntitySpaces.Proxies.Silverlight class library that houses our client side proxies? Well, there’s a reason we needed to have it housed in it’s own Silverlight class library and that is so we could tell Visual Studio to use it rather than generate proxies for us. Here’s how you do that when adding your Service Reference to the Silverlight application.

image

This is how we add our reference above. However, the trick to forcing Visual Studio to use our client side proxies is performed by pressing the “Advanced …” button.

image

Notice here that we tell it to reuse the types in our EntitySpaces.Proxies.Silverlight assembly. This is totally awesome. It’s great that Visual Studio allows us to do this. But even better, we were somewhat ahead of our time. Our client side proxies easily serialize into our server side proxies and vise versa. This is exactly what the DataContractSerializer is all about. It allows you to have different classes on each side of the conversation, and it works wonderfully in EntitySpaces.

Summary

This may seem like a lot to soak in but it really isn’t. We’ll be shipping our Silverlight demo hopefully with our next Alpha. Writing Silverlight applications is so graceful using EntitySpaces. Sure, you’re going to need to learn XAML and other things but all of the plumbing, wiring, and track have been laid for you. EntitySpaces has terrific Silverlight support. Everything you see here in this blog post works in our current alpha version. It’s late and we need to get some sleep, we are really jazzed about this and if anything we are understating how fantastic EntitySpaces is at providing the glue between Silverlight and WCF.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Tuesday, July 07, 2009 11:43:13 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, July 05, 2009

kick it on DotNetKicks.com

[UPDATED – SEE EntitySpaces, Silverlight, and WCF a Fantastic Combination FOR OUR NEW AND FAR SUPERIOR APPROACH]

Besides the enhancements mentioned in the DynamicQuery Enhancements post, this release addresses some important issues discovered in our previous alpha concerning Silverlight and WCF. You should uninstall the prior alpha before upgrading. Our Silverlight assembly is now named EntitySpaces.DynamicQuery.Silverlight.dll. There is, also, a new class called esDataContractSerializer (available in the .NET 3.5 assemblies) that can be used in any WCF or Silverlight application. Take a look at the code sample below which demonstrates an entire conversation from Server to Client and back to the Server again.  Using this approach all of your methods would use strings to send data to and receive data from the server. Of course, you can use the auto generated proxy classes created by Visual Studio but the nice thing about this approach is that the row-state of all of the data is maintained automatically and then saving becomes trivial.

public void TestCollection()
{
    EmployeesCollection coll = new EmployeesCollection();
    coll.Query.SelectAllExcept(coll.Query.Photo);
    coll.Query.es.Top = 3;

    if (coll.Query.Load())
    {
        // Create Our Server Side Proxy Stub
        BusinessObjects.EmployeesCollectionProxyStub server = new BusinessObjects.EmployeesCollectionProxyStub(coll);

        // Serialize it into a XML string and return this string to our Silverlight or WCF Client
        string xml = esDataContractSerializer.ToXml(server);

        // Deserialize the string above into our Client Side Proxy under Silverlight or our WCF Client
        Proxies.EmployeesCollectionProxyStub client = esDataContractSerializer.FromXml(xml, typeof(Proxies.EmployeesCollectionProxyStub))
            as Proxies.EmployeesCollectionProxyStub;

        // Set a property and notice that esRowState goes to Modified
        client.Collection[0].LastName = "Squarepants";

        // Serialize our Client Side Proxy into xml and send it back to the server
        xml = esDataContractSerializer.ToXml(client);

        // Deserialize it on the server back into a Server Side Proxy Stub, the esRowState is modifed as we would expect
        BusinessObjects.EmployeesCollectionProxyStub server1 = esDataContractSerializer.FromXml(xml, typeof(BusinessObjects.EmployeesCollectionProxyStub))
            as BusinessObjects.EmployeesCollectionProxyStub;

        // Now save the Entity
        server1.GetCollection().Save();
    }
}

You can also use this same approach with the single entity based proxies. For example, the EmployeeProxyStub class.

Some Silverlight / WCF Code

The PopulateEmployees() method below is the method that populates the grid in our soon to be released Silverlight demo. The method executes under Silverlight after the user types in his search criteria and hit’s the Search button. Notice that the query classes (both proxy and full server) contain their own ToXml / FromXml methods. This is because when we serialize and deserialize queries we are doing so for complex object graphs with circular references. This is more complex than what our esDataContractSerializer class is designed for.

private void PopulateEmployees()
{
    try
    {
        NorthwindClient.NorthwindClient service = new NorthwindClient.NorthwindClient();

        Proxies.EmployeesQueryProxyStub q = new Proxies.EmployeesQueryProxyStub("emp");
        q.Select(q.EmployeeID, q.FirstName, q.LastName, q.Title, q.HomePhone, q.HireDate, q.BirthDate);
        q.Where( q.FirstName.Like("%" + SearchTextBox.Text + "%") | q.LastName.Like("%" + SearchTextBox.Text + "%"));
        q.OrderBy(q.LastName.Ascending);
        q.es.Top = 5;

        // Notice we send the XML representation of the Query to the Server via the Async call “GetEmployees”
        service.GetEmployeesCompleted += GetEmployeesCompleted;
        service.GetEmployeesAsync(Proxies.EmployeesQueryProxyStub.SerializeHelper.ToXml(q));
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.StackTrace);
    }
}

The above code has called GetEmployees (a WCF service method on the server). This is what our WCF Service method on the server that receives the query looks like.

public string GetEmployees(string serializedQuery)
{
    List<Type> types = new List<Type>();
    types.Add(typeof(EmployeesQuery));

    // Deserialize our EmployeesQueryProxyStub class into our full blown server side query so we can execute it
    EmployeesQuery employeesQuery = EmployeesQuery.SerializeHelper.FromXml(
        serializedQuery, typeof(EmployeesQuery), types) as EmployeesQuery;

    EmployeesCollection employeesCollection = new EmployeesCollection();
    if (employeesCollection.Load(employeesQuery))
    {
        // Okay, we have loaded it, lets send the results back in string form
        EmployeesCollectionProxyStub proxy = new EmployeesCollectionProxyStub(employeesCollection);
        return esDataContractSerializer.ToXml(proxy);
    }

    return null;
}

Back under Silverlight in the browser our async GetEmployeesCompleted method is called, and we bind the data to the grid.

void GetEmployeesCompleted(object sender, GetEmployeesCompletedEventArgs e)
{
    try
    {
        WaitText.Visibility = Visibility.Collapsed;

        string serializedEmployees = e.Result;

        // Turn the XML into a Proxies.EmployeesCollectionProxyStub collection
        Proxies.EmployeesCollectionProxyStub employees = esDataContractSerializer.FromXml(
            serializedEmployees, typeof(Proxies.EmployeesCollectionProxyStub)) as Proxies.EmployeesCollectionProxyStub;

        // Now Databind
        EmployeesDataGrid.ItemsSource = employees.Collection;
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.StackTrace);
    }
}

This approach offers some real advantages. You can later send the serialized collection back to the server with added, updated, and deleted rows. Once on the server, deserialize it, and simply call Save on the full server side collection. This is because our proxies maintain the rowstate for you. We are still working out the kinks as we build our Silverlight application. The one problem we have right now is the Silverlight grid seems to revert back to the original data and lose our cell edits. However, this happens with the Visual Studio proxies as well. Once we get this issue resolved and are fully saving data, we will publish our Silverlight demo. If you want to use this technique, you will need to generate the client side proxies and include them in your Silverlight or WCF client application. Be sure and click the new checkbox named “Serializable Queries” on the Advanced Tab of the Generated Master template. However, as you can see from the DynamicQuery Enhancements post, we are doing more than just addressing Silverlight and WCF development.

The bug that was affecting project files has been fixed. This occurred if you edited a template instance in an existing project, and saved without visiting all of the tabs. With this fix, un-visited tabs no longer revert to their default values. There is also a Twitter toolbar button on the What’s New page so you can easily get to our Twitter page. This alpha still only supports Microsoft SQL Server.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Sunday, July 05, 2009 10:49:49 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, July 04, 2009

We have greatly improved the power of our DynamicQuery API, and there is still much more coming before our next official release goes into production. This is just a quick blog post to show some of the upcoming enhancements.

Full Expressions in OrderBy and GroupBy

This query doesn’t really make sense, but we wanted to show you what will be possible in the next release.

EmployeesQuery q = new EmployeesQuery();
q.Select(q.LastName.Substring(2, 4).ToLower());
q.OrderBy(q.LastName.Substring(2, 4).ToLower().Descending);
q.GroupBy(q.LastName.Substring(2, 4).ToLower());

EmployeesCollection coll = new EmployeesCollection();
if (coll.Load(q))
{
   string s = q.es.LastQuery;
}

The SQL Generated is as follows (and works)


SELECT SUBSTRING(LOWER([LastName]),2,4) AS 'LastName'
FROM [Employees]
GROUP BY SUBSTRING(LOWER([LastName]),2,4)
ORDER BY SUBSTRING(LOWER([LastName]),2,4) DESC

In the current production release 2009.1.0209.0, you can only use a “Column Name” in the OrderBy and GroupBy statements. In the upcoming release, you will be able use full expressions, just as you can now do in the Select statement.

Raw SQL Injection Everywhere

There may be times when you need to access some SQL feature that is not supported by our DynamicQuery API. But, now having used and fallen in love with DynamicQuery, the last thing you want to do is stop and go write a stored procedure or create a view. We have always supported the raw injection feature in our Select statement, but it will soon be available almost everywhere. The way it works is you pass in raw SQL in the form of a string surrounded by < > angle brackets. That indicates to the EntitySpaces dataproviders that you want the raw SQL passed directly to the database engine “as is”.

Here is an example query. You would never write a query like this in reality. EntitySpaces supports this simple query without having to use < > angle brackets. This is just to show all of the places that can accept the raw SQL injection technique:

EmployeesQuery q = new EmployeesQuery();
q.Select("<FirstName>", q.HireDate);
q.Where("<EmployeeID = 1>");
q.GroupBy("<FirstName>", q.HireDate);
q.OrderBy("<FirstName ASC>"); 

EmployeesCollection coll = new EmployeesCollection();
if (coll.Load(q))
{
    string s = q.es.LastQuery;
}

The SQL Generated is as follows (and works)

SELECT FirstName,[HireDate] AS 'HireDate' 
FROM [Employees] WHERE (EmployeeID = 1)
GROUP BY FirstName,[HireDate]
ORDER BY FirstName ASC

Of course, you could easily write the above query without injection, but you get the idea. The escape hatch will be available to you almost everywhere ….

EmployeesQuery q = new EmployeesQuery();
q.Select(q.FirstName);
q.Where(q.EmployeeID == 1);
q.OrderBy(q.FirstName.Ascending);
q.GroupBy(q.FirstName, q.HireDate);

Using the raw SQL injection techniques above will allow you to invoke SQL functions that we don’t support, including database vender specific SQL, and so on. Hopefully, you will almost never have to resort to writing a custom load method to invoke a stored procedure or an entirely hand written SQL statement. Of course, you can use our native API everywhere and just inject the raw SQL on the GroupBy for instance. You can mix and match to get the desired SQL.

There’s much more to come in this release …  Just last night we were serializing DynamicQuery’s from a Silverlight application and sending them to a WCF server to fetch the data… very slick. Watch for an upcoming blog post on our Silverlight demo very soon.

EntitySpaces

From Mobile Devices to large scale enterprise solutions in need of serious transaction support, EntitySpaces can meet your needs. Whether you’re writing an ASP.NET application with Medium Trust requirements, a Mono application, or a Windows.Forms application, the EntitySpaces architecture is there for you. EntitySpaces is provider independent, which means that you can run the same binary code against any of the supported databases. EntitySpaces is available in both C# and VB.NET. EntitySpaces uses no reflection, no XML files, and sports a tiny foot print of less than 200k. Pound for pound, EntitySpaces is one tough, dependable .NET architecture.

EntitySpaces LLC
Persistence Layer and Business Objects for Microsoft .NET
http://www.entityspaces.net

posted on Saturday, July 04, 2009 11:06:11 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]