Tuesday, June 24, 2008

ProLINQ



 

 

"EntitySpaces is an easy-to-use, high-performing .NET Object Relational Mapping (ORM) tool. If your organization is evaluating ORM tools, I would recommend that you add EntitySpaces to your list."   -- Vijay P. Mehta

 

 

 

 


While this book isn't specifically about EntitySpaces we do get some kinds words from it's author in the section of the book that does takes a look at EntitySpaces.

Author Information


Vijay P. Mehta has been working as a software engineer and architect for the last 12 years. Starting off in the VC++/ATL, MFC, Win32, and VB6 worlds, Vijay later moved on to Java and .Net development. With his current focus on C# and .Net, Vijay holds a number of Microsoft certifications and has written a number of articles on .Net and Microsoft–focused development. Currently working as an Architect for a financial services software company in Indianapolis, Vijay spends the bulk of his time designing and implementing large, cutting-edge software systems.

For more information see Pro LINQ Object Relational Mapping in C# 2008

 


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

posted on Tuesday, June 24, 2008 5:45:39 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, May 24, 2008
kick it on DotNetKicks.com

I have always built architectures on top of ADO.NET DataTables, they're fast (yes), flexible, and the power it provides is really pretty good. Additionally, as new features are added to ADO.NET they can then be easily absorbed. We were able to add LINQ to SQL to EntitySpaces by simply turning a LINQ query into an ADO.NET DataTable. Once we exchange the LINQ query for an ADO.NET DataTable the EntitySpaces architecture functions as normal since its underlying data structure is a DataTable. Pretty sweet. Here's a nice little trick in case you are not aware of it.

DataContext context = new DataContext("User ID=sa;Initial Catalog=ForeignKeyTest;Data Source=localhost;");

var linqQuery = context.GetTable<Employee>().Where(s => s.LastName != "Griffin")
    .OrderBy(s => s.LastName);

SqlCommand cmd = context.GetCommand(linqQuery) as SqlCommand;

DataTable dataTable = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataTable);

There you have it. A DataTable obtained from a LINQ query, easy as pie.  You can simply ask the DataContext for a Command object and then use the Command object in combination with a DataAdapter to fill a DataTable. This is exactly what EntitySpaces 2008 does under the covers. This is an excellent way for architectures to leverage the power of LINQ to SQL.

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.

The EntitySpaces Team
--

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

posted on Saturday, May 24, 2008 3:04:44 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Friday, May 23, 2008

EntitySpaces and Silverlight Demo

Part 2: Filtering and Changing EntitySpaces Data

kick it on DotNetKicks.com

Jon_Davis
Written by Jon Davis
http://www.jondavis.net/

 

 

Run the Demo Here  ==> http://developer.entityspaces.net/ES2008/Demos/Silverlight/PartTwo
Download the Source Here ==> http://www.developer.entityspaces.net/downloads/EntitySpacesSilverlightDemo2.zip 
 

Review of Part One

In Part One, I described the process of getting Silverlight to interact with a WCF web service, and I showed how I bound EntitySpaces based data objects (WCF client proxies) to Silverlight controls, specifically a DataGrid control. While there were a lot of pages of review in Part One, it was mostly point-and-click “configuration coding”, as MyGeneration, EntitySpaces, and Visual Studio did most of the work for me.

linqII_one

Figure 1 - EntitySpaces RIA running in Safari 3.1 (on Windows) with just about 20 lines of hand-written client-server code and XAML markup.

 

But showing data in a grid isn’t very exciting. It’s time to look at some interaction with data and give EntitySpaces a little more credit than just a data wrapper.

 

Category-Filtered Products (Client-Server Method)

Let’s assume that the user wants to filter the products list by category. I want to keep this demonstration as simple as possible, while proving out technical implementations of basic scenarios, so I’m not going to make any significant effort just yet to make this look pretty.

linqII_two  

Here’s the XAML:

<UserControl
    x:Class="EntitySpacesSilverlightDemo_Silverlight.Page"
    xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="Gray">
        <Grid.RowDefinitions>
            <RowDefinition Height="75" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="EntitySpaces on Silverlight ~ Northwind Demo" VerticalAlignment="Center" HorizontalAlignment="Center" />
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>

            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="Please Wait" Visibility="Collapsed" x:Name="WaitText" />
            <ListBox Width="300" Grid.Column="0" x:Name="ViewSelector" SelectionChanged="ViewSelector_SelectionChanged">
                <ListBoxItem Content="Products: All"></ListBoxItem>
            </ListBox>

            <Controls:DataGrid AutoGenerateColumns="True" x:Name="ESDataGrid" Grid.Column="1" />
        </Grid>
    </Grid>
</UserControl>

For starters and for the sake of continuing the discussion of ES over WCF, I’m going to make this a client-server filter—I’ll pass in a CategoryID as a parameter in my WCF request for products.

Here’s the complete client-side code-behind for Page.xaml.cs, additions in bold+brown:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net;

using EntitySpacesSilverlightDemo_Silverlight.Northwind;

namespace EntitySpacesSilverlightDemo_Silverlight
{
    public partial class Page : UserControl
    {
        NorthwindClient.NorthwindClient ESNorthwind;

        public Page()
        {
            InitializeComponent();
            ESNorthwind = new NorthwindClient.NorthwindClient();

            ESNorthwind.GetCategoriesCompleted += ApplyCategoriesToList;
            ESNorthwind.GetProductsCompleted += new EventHandler<NorthwindClient.GetProductsCompletedEventArgs>(NorthwindClient_GetProductsCompleted);
            ESNorthwind.GetProductsByCategoryCompleted += new EventHandler<GetProductsByCategoryCompletedEventArgs>(Northwind_GetProductsByCategoryCompleted);

            GetCategories();

            LoadAllProducts();
        }

        private void GetCategories()
        {
            ESNorthwind.GetCategoriesAsync();
        }

        private void ApplyCategoriesToList(object sender, GetCategoriesCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                Categories[] cc = e.Result.Collection;
                for (int i = cc.Length-1; i >=0; i--)
                {
                    Categories category = cc[i];
                    ListBoxItem lbi = new ListBoxItem();
                    lbi.Tag = "CategoryID: " + category.CategoryID;
                    lbi.Content = "Products: " + category.CategoryName;
                    ViewSelector.Items.Insert(1, lbi);
                }
            }
        }

        private void LoadAllProducts()
        {
            WaitText.Visibility = Visibility.Visible;
            ESNorthwind.GetProductsAsync();
        }

        void LoadProductsByCategory(int categoryId)
        {
            WaitText.Visibility = Visibility.Visible;
            ESNorthwind.GetProductsByCategoryAsync(categoryId);
        }

        void Northwind_GetProductsByCategoryCompleted(object sender, GetProductsByCategoryCompletedEventArgs e)
        {
            WaitText.Visibility = Visibility.Collapsed;
            ProductsCollection pc = e.Result;
            ESDataGrid.ItemsSource = pc.Collection;
        }

        void NorthwindClient_GetProductsCompleted(object sender, Northwind.GetProductsCompletedEventArgs e)
        {
            WaitText.Visibility = Visibility.Collapsed;
            ProductsCollection pc = e.Result;
            ESDataGrid.ItemsSource = pc.Collection;
            ESDataGrid.Columns[ESDataGrid.Columns.Count - 1].Visibility = Visibility.Collapsed; // hide "esRowState"
        }

        private void ViewSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBoxItem lbi = ViewSelector.SelectedItem as ListBoxItem;
            if (lbi != null)
            {
                if (lbi.Content.ToString() == "Products: All")
                {
                    LoadAllProducts();
                    return;
                }
                string tag = lbi.Tag as string;
                if (tag != null && tag.StartsWith("CategoryID: "))
                {
                    tag = tag.Substring(12);  // length of "CategoryID:"
                    LoadProductsByCategory(int.Parse(tag));
                }
            }
        }

    }
}

On the server, we will perform a basic EntitySpaces query operation.

INorthwind service interface:
[ServiceContract]
public interface INorthwind
{
    [OperationContract]
    ProductsCollectionProxyStub GetProducts();

    [OperationContract]
    ProductsCollectionProxyStub GetProductsByCategory(int categoryId);
    [OperationContract]
    CategoriesCollectionProxyStub GetCategories();
}

Northwind service implementation:
public class Northwind : INorthwind
{
    public ProductsCollectionProxyStub GetProducts()
    {
        ProductsCollection pc = new ProductsCollection();
        pc.LoadAll();
        ProductsCollectionProxyStub pcs = new ProductsCollectionProxyStub(pc);
        return pcs;
    }

    public ProductsCollectionProxyStub GetProductsByCategory(int categoryId)
    {
        ProductsCollection pc = new ProductsCollection();
        pc.Query.Where(pc.Query.CategoryID.Equal(categoryId));
        pc.Load(pc.Query);

        ProductsCollectionProxyStub pcs = new ProductsCollectionProxyStub(pc);
        return pcs;
    }

    public CategoriesCollectionProxyStub GetCategories()
    {
        CategoriesCollection cc = new CategoriesCollection();
        cc.LoadAll();

        // strip out the OLE bitmaps
        for (int i = 0; i < cc.Count; i++)
        {
            cc[i].Picture = null;
        }

        CategoriesCollectionProxyStub ccs = new CategoriesCollectionProxyStub(cc);
        return ccs;
    }

}

Category-Filtered Products (Local Filtering Method)

Practically speaking, calling out to the server every time you want to filter the products is bad design unless the Products list contains a lot (hundreds of thousands) of records, in which case we should also drop the “Products: All” unfiltered option from the ListBox so that the user cannot make the mistake of loading all products which might take forever.

If the unfiltered source data is relatively small, as Northwind’s Products table actually is, then it would make more sense to load all products from the server and then filter against the category locally. This eliminates the HTTP-based callback to the server and makes the user’s experience much faster and more responsive.

LINQ-to-Objects is supported in Silverlight, and this includes LINQ-to-EntitySpaces-client-proxies. We can change the NorthwindClient_GetProductsCompleted and ViewSelector_SelectionChanged methods to use LINQ filtering rather than server-side filtering. In so doing, we can remove much of the code we just added and achieve the same results but executing much faster.

Products[] NorthwindProducts = null;
void NorthwindClient_GetProductsCompleted(object sender, Northwind.GetProductsCompletedEventArgs e)
{
    WaitText.Visibility = Visibility.Collapsed;
    NorthwindProducts = e.Result.Collection;
    ESDataGrid.ItemsSource = NorthwindProducts;
    ESDataGrid.Columns[ESDataGrid.Columns.Count - 1].Visibility = Visibility.Collapsed; // hide "esRowState"
}

private void ViewSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBoxItem lbi = ViewSelector.SelectedItem as ListBoxItem;
    if (lbi != null)
    {
        if (lbi.Content.ToString() == "Products: All")
        {
            ESDataGrid.ItemsSource = NorthwindProducts;
            ESDataGrid.Columns[ESDataGrid.Columns.Count - 1].Visibility = Visibility.Collapsed; // hide "esRowState"
            return;
        }
        string tag = lbi.Tag as string;
        if (tag != null && tag.StartsWith("CategoryID: "))
        {
            int catID = int.Parse(tag.Substring(12));
            ESDataGrid.ItemsSource =
                from p in NorthwindProducts
                where p.CategoryID == catID
                select p;
            ESDataGrid.Columns[ESDataGrid.Columns.Count - 1].Visibility = Visibility.Collapsed; // hide "esRowState"
        }
    }
}

We can now eliminate one of the INorthwind interfaces we just added, ..

  • GetProductsByCategory(int categoryId)

.. and we can eliminate some of the just-added client/server handling code in Silverlight:

  • LoadProductsByCategory(int categoryId)
  • Northwind_GetProductsByCategoryCompleted(...)

Changing Data

Let’s assume that the user is an administrator who is maintaining this list of products and needs to be able to make changes to product data on the fly. The bad news is that in the interest of focusing on EntitySpaces and less on Silverlight UI, I intended to refrain from creating a pop-up editor for editing a record. The good news is that the Silverlight DataGrid supports two-way databinding and inline edits, and in such case one would need no layout changes at all. I only need to add an event handler for DataGrid edits and pass the revised record up to the server via WCF.

We’ll bind to the CommittingCellEdit and CommittingRowEdit events. In CommittingCellEdit we’ll update the property that was edited, and in CommittingRowEdit we’ll pass the Product out to the server.

Page.xaml (modify):

<Controls:DataGrid AutoGenerateColumns="True" x:Name="ESDataGrid" Grid.Column="1"
CommittingCellEdit="ESDataGrid_CommittingCellEdit"
CommittingRowEdit="ESDataGrid_CommittingRowEdit"
/>

Page.xaml.cs (add):

private void ESDataGrid_CommittingCellEdit(object sender, DataGridCellCancelEventArgs e)
{
    Products p = (Products)e.Row.DataContext;
    string f = e.Column.Header.ToString();
    string v = ((TextBox)e.Element).Text;
    System.Reflection.PropertyInfo pi = p.GetType().GetProperty(f);
    if (pi.PropertyType == typeof(string))
    {
        pi.SetValue(p, v, null);
    }
    else if (pi.PropertyType == typeof(int) ||  pi.PropertyType == typeof (int?))
    {
        pi.SetValue(p, int.Parse(v), null);
    }
    else e.Cancel = true;
    if (!e.Cancel)
    {
        p.esRowState = "Modified";
    }
}

private void ESDataGrid_CommittingRowEdit(object sender, DataGridRowCancelEventArgs e)
{
    Products p = (Products)e.Row.DataContext;
    if (p.esRowState == "Modified")
    {
        ESNorthwind.UpdateProductAsync(p);
    }
}

This won’t compile until we revise our service in the Web project and then update the reference to it in the Silverlight project.

INorthwind.cs (add):

[OperationContract]
void UpdateProduct(ProductsProxyStub product);

AppCode/Northwind.cs (or Northwind.svc.cs, add):

public void UpdateProduct(ProductsProxyStub product)
{
    Products prod = (Products)product.GetEntity();
    prod.Save(); // wow, that was easy..
}

Silverlight project:

linqII_three

Now the Silverlight code should compile, and if you set breakpoints both on the server’s UpdateProduct() method as well as on the new event handler in Silverlight, you should be able to watch the data model as it gets updated and sent back to the server.

Recommitting back to the server was so easy (although the reflection bits in the CommitingCellEdit event handler needs some clean-up) it’s actually a little dangerous. We can’t go live with this change on a public demo without having a nightly automated process to restore the Northwind data or else it will become unusable.

But this tutorial should have still sufficed in getting you on your feet with fetching, filtering, and updating data between Silverlight and EntitySpaces. There is a lot of design-related knowledge to be had in Silverlight, and real-world business objects to be realized in EntitySpaces, but this was a basic data discussion, so the rest is up to you.

 


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.

The EntitySpaces Team
--

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

posted on Friday, May 23, 2008 10:15:53 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, May 11, 2008

Oh, I almost forgot the most important thing. And that is using LINQ to SQL to populate data directly into your EntitySpaces collections, oh man this is hot !!

DataContext context = new DataContext("User ID=sa;Initial Catalog=Northwind;Data Source=localhost;");

var linqQuery = context.GetTable<Employees>().Where(s => s.LastName == "Griffin")
    .OrderBy(s => s.LastName);

EmployeesCollection coll = new EmployeesCollection();
coll.Load(context, linqQuery);

foreach (Employees emp in coll)
{
    Console.WriteLine(emp.FirstName);
}

Notice that we pass the context and the linqQuery directly into our EntitySpaces EmployeeCollection's Load() method, the rest is the same as usual, awesome !!

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.

The EntitySpaces Team
--

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

posted on Sunday, May 11, 2008 10:37:53 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

Although this didn't make our Beta III release our LINQ support is already in the new templates for the next Beta (we're getting close to a final beta but not yet). Before we show you how it all works let's look at some examples to peak your interest.

First lets select all Employees who have the last name "Griffin" and order them as well. The Employees class highlighted in blue above is your true EntitySpaces class.

DataContext context = new DataContext("User ID=sa;Initial Catalog=Northwind;Data Source=localhost;");

var q = context.GetTable<Employees>().Where(s => s.LastName == "Griffin")
    .OrderBy(s => s.LastName);

foreach (Employees emp in q)
{
    Console.WriteLine(emp.LastName);
}

Now let's do a join using a different syntax style. Notice that we select the EmployeeID from the Empoyees table and the OrderID from the Orders table.

DataContext context = new DataContext("User ID=sa;Initial Catalog=Northwind;Data Source=localhost;");

var employees = context.GetTable<Employees>();
var orders = context.GetTable<Orders>();

var query = from e in employees
            join o in orders on e.EmployeeID equals o.EmployeeID
            where e.LastName != "Griffin"
            select new { e.EmployeeID, o.OrderID };

foreach (var obj in query)
{
    Console.WriteLine(obj .EmployeeID.ToString() + ":" + obj .OrderID.ToString());
}

To add LINQ to SQL support to your EntitySpaces classes all you need to do is check a checkbox on the advanced tab.

When you check this checkbox the templates will make sure our LINQ to SQL support is injected in your classes. The code ends up looking like this.

[Serializable]
[Table(Name = "Employees")]
public partial class Employees : esEmployees
{
    #region LINQtoSQL overrides

    [Column(IsPrimaryKey = true, CanBeNull = false)]
    public override System.Int32? EmployeeID
    {
        get { return base.EmployeeID; }
        set { base.EmployeeID = value; }
    }

    [Column(IsPrimaryKey = false, CanBeNull = false)]
    public override System.String LastName
    {
        get { return base.LastName; }
        set { base.LastName = value; }
    }

    [Column(IsPrimaryKey = false, CanBeNull = false)]
    public override System.String FirstName
    {
        get { return base.FirstName; }
        set { base.FirstName = value; }
    }

    [Column(IsPrimaryKey = false, CanBeNull = true)]
    public override System.String Title
    {
        get { return base.Title; }
        set { base.Title = value; }
    }

    // and so on ....

    #endregion
}

Of course you will need to be targeting .NET 3.5 and the generated classes will include these additional namespaces:

using System.Data.Linq;
using System.Data.Linq.Mapping;

This will work for any .NET Providers that support LINQ to SQL, currently I believe that is only Microsoft's SQL Client (but I could be wrong, I know the Npgsql guys are working on this too). So, now you can have all of the wonderful EntitySpaces features, including our Dynamic API (which runs on all of our supported databases and .NET 2.0) and LINQ as well if you so choose.

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.

The EntitySpaces Team
--

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

 

posted on Sunday, May 11, 2008 8:03:39 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, April 27, 2008
kick it on DotNetKicks.com

imageThe EntitySpaces 2008 Beta II is now available. The version number is 2008.0.0427.0 and is available for download now on our home page. You should uninstall any prior ES2008 alpha or beta that you may have installed. You can run ES2007 and ES2008 side-by-side. Do not install ES2008 over the top of ES2007. EntitySpaces 2008 has proven to be a big undertaking. Every EntitySpaces template has been rewritten using our new metadata engine and is now supported in both MyGeneration and CodeSmith, many were converted from VBScript to C#. However, from this point forward we start knocking off issues on our roadmap in rapid fire fashion. We are a little behind on our May 15th release date, but not too far. Not only is the trial available for download but both the Developer version and Source version are available to customers as well.

The testing behind this release is tremendous. We have two code generators in play, C# and VB.NET templates, and to top it off we had to debug Oracle subquery issues with messages like "ORA-923 No worky, try again" (kidding, but only slightly). Throw in database independence, the Compact Framework, and you really have your hands full. However, we are over the hump now and can see the light. This is a little off topic but we cannot wait to put up our Silverlight demo showing EntitySpaces working hand-in-hand with Silverlight. Our Silverlight demo is being worked on by Jon Davis and when we saw his first cut we were very impressed, Jon is a very sharp guy indeed.

We've made some good changes too with our installs. Both our Trial and Developer versions install exactly in the same folder structures. This will avoid confusion for those folks who use the EntitySpaces Trial for a large part of their development process and then purchase the Developer version before going live. Now you can simply install the developer version right over the top of the trial and not worry about changing reference paths. This beta comes with all providers, including our Compact Framework providers, it also comes with a SQL CE desktop provider in addition to the Compact Framework version. The beta will automatically install into both MyGeneration 1.2 and 1.3 folders and add support for CodeSmith. See the Getting Started documents on your menu after installation. There is a "Getting Started.PDF" for both MyGeneration and CodeSmith. Just a quick note for our MyGeneration customers. If you have any user meta data defined for aliases or Oracle or PostgreSQL sequences be sure to run the UserData template. It will convert the MyGeneration user data file to our new format upon first run. From that point on you maintain your user meta data via our UserData template and not through MyGeneration.

image

You can see by the image on the right that the runtimes are easily found in the Runtimes folder. We have both .NET 2.0 and 3.5 assemblies as well as Compact Framework assemblies (we now use CF and not Ce for those in our naming convention). Also notice that the CodeSmith templates are under the EntitySpaces 2008 folder. The "Getting Started.PDF" for CodeSmith will show you how to setup a Template Folder Shortcut in CodeSmith, it's a snap.

Our ES2007 EntitySpaces demo still hasn't been converted thus our ES2008 demo is very lightweight. We are going to rewrite it and not just convert it so that's the reason why we've held off. There could be some minor breaking changes coming when we tackle a few things on the roadmap, however that's not the usual case for EntitySpaces. We do want to address a few things to make your lives easier though.

We really hope a lot of our users start taking a serious look at ES2008, our Subquery and Casting support is very powerful and we will have a ton of enhancements rolling out soon as we head for the official release. We have also prototyped LINQ to SQL with EntitySpaces. And even more exciting when talking to Jon Davis about Silverlight we spoke about adding the very popular EntitySpaces DynamicQuery API to our proxies as an option. You could then issue full ES2008 dynamic queries from within Silverlight (down in the client) and from other situations such as WCF conversations where you might not have EntitySpaces on the client. All of this is to say that when we release EntitySpaces 2008 that is not the end, but the beginning.

We are very excited about where we are going and have a great vision for EntitySpaces. Not only can we run on Mono, Medium Trust, the Compact Framework, but we can provide seamless support for Silverlight as well. Mike Griffin will be demonstrating a lot of these high end features at the Indy ALT.NET meeting on May 15th.

So download the ES2008 Trial and if you hit a snag please post on the forums and we'll get you a speedy response.


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.

The EntitySpaces Team
--

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

posted on Sunday, April 27, 2008 9:22:04 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, April 13, 2008
kick it on DotNetKicks.com

beach


Vacation

If you noticed that I wasn't around much on the forums this past week you weren't imagining things. I was on vacation in Palm Beach Gardens, Florida. It's truly paradise on earth. We went to Juno Beach almost every day (don't let the Jones Beach shirt fool you). I was there with my wife and three children and we played in the waves all week, it was awesome. Maybe I'll post some other photos later. I have to admit it's a little depressing to be back in Indianapolis and it's only 39 degree's here (it was in the mid 80's all week in Florida).

During the evenings I was able to read the new LINQ in Action book published by Manning. I was particularly interested in the LINQ to SQL functionality and how it could be applied to EntitySpaces. Well, it's been less than 24 hours since I've been home and I already have LINQ to SQL working with EntitySpaces. The LINQ in Action book is pretty good as a LINQ reference but it really kind of ticked me off otherwise. The strawman it setup in order to tear down was really blatant. I think I could take nearly all of the the supposed samples it uses to show how much better LINQ is over ADO.NET and provide appropriate samples using EntitySpaces and it would be far more intuitive. I might just do that later to make a point.

Okay, enough ranting, let's focus on using EntitySpaces with LINQ to SQL (for Microsoft SQL Server only so far).

EntitySpaces and LINQ to SQL

Adding support to EntitySpaces for LINQ to SQL was pretty easy. I added [Table] and [Column] attributes from the System.Data.Linq.Mapping namespace to my "generated" Employee entity like so:


[Table(Name="Employee")]
public partial class Employee : esEmployee
{
    [Column(IsPrimaryKey = true, CanBeNull = false)]
    public override int? EmployeeID
    {
        get { return base.EmployeeID;  }
        set { base.EmployeeID = value; }
    }

    [Column]
    public override string LastName
    {
        get { return base.LastName;  }
        set { base.LastName = value; }
    }

    // more properties here ...
}

I had to make pass through's for the properties however. Recall that the properties are in the generated esEmployee class not the generated Employee class and the esEmployee class is abstract. LINQ cannot instantiate the abstract esEmployee class and it appears that the [Table] and [Column] attributes must be on the same physical class (no inheritance allowed). So I made overrides of the properties in my Employee class, applied the attributes, and I was ready to test. For more information on the inheritance LINQ limitation see this MSDN forum post.

After making the above changes it was time to test it and see if worked. Below is my test code.

DataContext dataContext = new DataContext("User ID=sa;password=; ... ");

var employees = dataContext.GetTable<Employee>();
var query = from employee in employees where employee.Age < 50 select employee;

foreach (Employee emp in query)
{
    Console.WriteLine(emp.Age.ToString());
}

As I suspected and hoped, it worked. However, semantically this is a little different that using our DynamicQuery API. I didn't get back an EntitySpaces EmployeesCollection class. Instead I was handed a System.Linq.IQueryable<BusinessObjects.Employee> interface which I could then use to enumerate over the individual Employee objects. However, these were my true EntitySpaces objects which was kind of cool. This is all still exploratory and is slower than using the EntitySpaces DynamicQuery API but still offers valuable functionality. We're pushing hard on the next ES2008 beta and as time allows we will sneak in some of these cool new features as time allows. My guess is this will make the first release of ES2008.

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.

The EntitySpaces Team
--

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

posted on Sunday, April 13, 2008 12:32:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, April 06, 2008

We are cranking very hard on EntitySpaces 2008. However, we are doing many things in parallel. We thought we would take this time to relay some of work going on here at EntitySpaces behind the scenes and to relay some long term strategy. None of these side tasks are drawing tremendous energy away from our main focus, which is, EntitySpaces 2008.

 

Side Tasks

 

Silverlight

 

We are working with a Silverlight expert to create a sample that demonstrates running EntitySpaces under Silverlight. These are the scenarios we are investigating:

 

1) Hosting the EntitySpaces assemblies under Silverlight in the browser.

2) Hosting our lightweight proxies under Silverlight in the browser.

 

This research is just getting underway and will let you know more soon. The idea is to make it so that you can write Silverlight pages using EntitySpaces. We know in some form this will be possible.

 

Site Redesign

 

EntitySpaces is undergoing a site redesign and logo change. Our goal is to make the changeover simultaneously with the release of ES2008.

 

LINQ to SQL

 

There is some investigation underway that might allow our Microsoft SQL users to check a checkbox during the code generation process that would allow them to use native LINQ to SQL calls to populate EntitySpaces. This is very much at the beginning of the R&D process. However, we are not creating our own LINQ provider. If we can offer you LINQ through the existing providers then we will do so. We are very committed to our DynamicQuery API and will continue to expand it in big ways. In no way will LINQ replace our DynamicQuery API.

 

The .NET Micro Framework

 

We will investigate this at some point after ES2008 is shipped. Whether or not it makes sense for us to support the .NET Micro Framework we are unsure of at this time. We are committed to ensuring that EntitySpaces remains tiny and continues to run under all possible .NET environments. Our Mono support and Compact Framework support will always be very important to us.

 

Long Term

 

After we ship EntitySpaces 2008 we will begin to solidify the design goals of our next release. The ES2008 release essentially decouples us from any particular code generator. We now use our own metadata engine and essentially only use code generators to gather the user input and execute our templates. Our templates are really just normal ASP.NET pages with <% %> tags and literal content and this is inline with our long term goals.

 

Visual Studio Shell

 

We have done some investigation into the Visual Studio Shell (both integrated and isolated) and we think this could be the platform we choose to go with long term. This would mean that we would no longer use code generators and instead would do the code generation ourselves. Since the Visual Studio Shell supports isolated mode this has the added advantage of still supporting the smaller shops that cannot afford Visual Studio (integrated runs inside of Visual Studio itself).

 

The Modeler

 

EntitySpaces will support custom domain model building. We currently generate the hierarchical object model from the foreign keys in the database. In the future, and in conjunction with the VS Shell application mentioned above, you will be able to design your own object model that is not tied to the physical database schema. However, we will not use XML or other such devices at runtime, we will simply generate the code using your virtual domain model. We will still support our current approach which is solely based on the database schema also.

 

Template Engine

 

Imagine a template engine that is based on snippets. Currently we have Master templates which execute sub-templates where a sub-template might be and entity class, a collection class, or query class. Our new template engine will be based on snippets. A sub-template itself would merely be a collection of snippets where each little "set" of functionality is a snippet. Writing a snippet would be very simple and within the grasp of all developers.


A snippet could be a property creation snippet, an INotifyChanged snippet, and so on. This would allow users to swap in their own snippets as well as to share them. Our standard templates would be based on many individual snippets. To customize or extend EntitySpaces would no longer require hand changing templates, simply restack and or replace the snippets through a UI not hand editing.

Our shell based application would have its own underlying database which would store templates and other settings. You would be working with templates graphically, where each snippet is a different colored block. You could then right mouse on a snippet and choose remove it and drag and drop other snippets from the available snippet library onto a template to further customize it. Users will be able to post snippets to an online webservice hosted by EntitySpaces that our shell app will make available to all EntitySpaces users. At some point, after ES008 ships, we will post some images of our new approach.

We feel this is going to revolutionize the way people view code generation as we will open this up to the masses, not to just code generation experts. The Visual Studio Shell combined with our new Modeler will take our already stellar architecture to new levels.

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.

The EntitySpaces Team
--

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

posted on Sunday, April 06, 2008 11:24:03 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Wednesday, September 19, 2007

I just had to make another post, this is so much fun. Writing queries in our enhanced dynamic query language is totally awesome, and so powerful. I'm writing some unit tests to go into our massive NUnit test suite and just had to post these ...

public void JoinWithArithmeticExpressionOrderByCalulatedColumn()
{
    // Notice I create a calulated columns based on the TotalSales, then Order by it descending
    CustomerQuery cust = new CustomerQuery("c");
    OrderQuery order = new OrderQuery("o");
    OrderItemQuery item = new OrderItemQuery("oi");

    cust.Select(cust.CustomerName, (item.Quantity * item.UnitPrice).Sum().As("TotalSales"));
    cust.InnerJoin(order).On(order.CustID == cust.CustomerID);
    cust.InnerJoin(item).On(item.OrderID == order.OrderID);
    cust.GroupBy(cust.CustomerName);
    cust.OrderBy("TotalSales", esOrderByDirection.Descending);

    CustomerCollection coll = new CustomerCollection();
    coll.Load(cust);
}

The SQL produced:

SELECT c.[CustomerName],SUM(oi.[Quantity]) AS 'TotalSales'
FROM [ForeignKeyTest].[dbo].[Customer] c
JOIN [ForeignKeyTest].[dbo].[Order] o ON (o.[CustID] = c.[CustomerID])
JOIN [ForeignKeyTest].[dbo].[OrderItem] oi ON (oi.[OrderID] = o.[OrderID])
GROUP BY c.[CustomerName]
ORDER BY TotalSales DESC

The result set is CustomerName / TotalSales sorted in decending order by TotalSales ...

Another query I wrote merely concatenated the Employee FirstName and LastName columns, and upper cased them.

public void ArithmeticConcatenationNoJoinWithSubOperator()
{
    EmployeeCollection coll = new EmployeeCollection();
    EmployeeQuery q = coll.Query;

    q.Select( (q.LastName + "," + q.FirstName).ToUpper().As("FullName") );
    q.OrderBy(q.LastName.Ascending);

    coll.Query.Load();
}

I've seen many of our competitors query languages, I think by far EntitySpaces has the cleanest, most straight-forward syntax, by light years in most cases. We've got some really cool stuff coming, hang on ...

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, 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.

The EntitySpaces Team
--

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


kick it on DotNetKicks.com
posted on Wednesday, September 19, 2007 7:47:35 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Tuesday, September 18, 2007

The EntitySpaces Dynamic Query API will soon be sporting Join’s and Arithmetic Expressions. The syntax is so elegant even LINQ enthusiasts will take pause. Let’s take a look at how you would do a join using the enhanced EntitySpaces DynamicQuery. Note that we are using all of your existing objects to build the query.

Performing Joins …

CustomersQuery cust = new CustomersQuery ("c");
OrdersQuery orders = new OrdersQuery ("o");
OrderDetailsQuery details = new OrderDetailsQuery ("d");

cust.Select(cust.ContactName, details.Quantity.Sum().As("TotalQuantity"));
cust.InnerJoin(orders).On(cust.CustomerID == orders.CustomerID);
cust.InnerJoin(details).On(orders.OrderID == details.OrderID);
cust.Where(cust.ContactName.Like("%Mike%"));
cust.GroupBy(cust.ContactName);

CustomersCollection coll = new CustomersCollection ();
coll.Load(cust);    // Load it …

Now that is a pretty sweet syntax …

Of course, RightJoin, LeftJoin, and FullJoin are also supported. The nice thing about this approach is that you are spoonfed the syntax via intellisense, no need to stop and create a view (although you can if you want to and generate your business entities off of the view). The "o", "c" and "c" shown above are merely the aliases used when building the SQL.

Arithmetic Expressions

You can now use arithmetic expressions in your query's. Notice how you can use the natural language syntax with * / + - and %. Take a look at this sample …

CustomersQuery cust = new CustomersQuery ("c");
OrdersQuery orders = new OrdersQuery ("o");
OrderDetailsQuery details = new OrderDetailsQuery ("d");

cust.Select(cust.ContactName, (details.Quantity * details.Price).Sum().As("TotalPrice"));
cust.InnerJoin(orders).On(cust.CustomerID == orders.CustomerID);
cust.InnerJoin(details).On(orders.OrderID == details.OrderID);
cust.Where(cust.ContactName.Like("%Mike%"));

CustomersCollection coll = new CustomersCollection ();
coll.Load(cust);    // Load it …

How Does this Effect Binding?

Your EntitySpaces collections will now provide a new method named LowLevelBind(). Normally, you bind directly to the properties in your EntitySpaces entities. However, when joins are in play you are bringing back columns that aren’t in your entities. Thus, the LowLevelBind will bind directly to the underlying DataTable. The are other ways of course using EntitySpaces but we wont cover those in this post.

grid.DataSource = coll.LowLevelBind();

Can I still Save an Entity that was Built off a Join?

The answer is "yes". Of course, it will only save to the main table, in the above case the Customer table.
We already have this implemented and are hoping to have a beta out with joins and arithmetic expressions around October 1st, 2007.

These new features will be available for all of the many databases supported by EntitySpaces.

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, 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.

The EntitySpaces Team
--

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

posted on Tuesday, September 18, 2007 11:22:28 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]
 Sunday, February 25, 2007

Another area of enhancement is complete, and that is our improvements to the EntitySpaces Dynamic Query API. We took some steps not covered in this blog post to hide extraneous items from the intellisense when building Dynamic Query's via intellisense. We have also opened the door to all kinds of SubOperators, some simple samples are shown below, of course these work on all of the EntitySpaces data providers as well. It is our hope that during our 1.6 beta our users will suggest more SubOperators, and as long as they apply across most databases there's a good chance they will make the release.

So here's the Sneak Peak ...


Notice the ToLower() SubOperator and the As() aliasing mechanism. These are both new to the 1.6 DynamicQuery Mechanism.

Employees emp = new Employees();
emp.Query.Select(emp.Query.LastName.ToLower().As("LastNameLower"));
emp.Query.Where(emp.Query.EmployeeID == 1);
emp.Query.Load();

Generates ...

SELECT LOWER([LastName]) AS 'LastNameLower' FROM [Employees] WHERE ([EmployeeID] = @EmployeeID1)



Notice the LTrim and Substring SubOperators as well as the As aliasing mechanism

Employees emp = new Employees();
emp.Query.Select(emp.Query.LastName.LTrim().Substring(0,1).As("FirstInitial"));
emp.Query.Where(emp.Query.EmployeeID == 1);
emp.Query.Load();

Generates ...

SELECT LTRIM(SUBSTRING([LastName],0,1)) AS 'FirstInitial' FROM [Employees] WHERE ([EmployeeID] = @EmployeeID1)



Finally, the Aggregates underwent a breaking change, it will be very easy to upgrade these and we felt it important to have our Aggregates conform with the rest of the syntax. We apologize for the breaking change but felt it important to make this change now. We feel that when you look at the two syntax's shown below you will agree the 1.6 syntax is superior and really shines with intellisense.

1.5.3 Syntax
emp.Query.Select(emp.Query.LastName.Count("TheCount", true));

1.6.0 Syntax
emp.Query.Select(emp.Query.LastName.Count().Distinct().As("TheCount"));



The SubOperators that will be available in the 1.6 March 4th beta are as follows:

  • ToUpper
  • ToLower
  • LTrim
  • RTrim
  • Trim
  • Substring

There are many more that can be implemented, the architecture is now in place to support them and the syntax nests properly as you can see in the Substring example above. Something we've been thinking about that won't make our 1.6 Release but will find it's way onto an upcoming Roadmap is SubSelects. We already support the IN in the where clause of course. We're not sure on the syntax but perhaps something like this:

Future Roadmap ....

Customers cust = new Customers();
Employees emp = new Employees();

emp.Query.Select(emp.Query.EmployeeID, emp.Query.FirstName);
emp.Query.Where(emp.Query.EmployeeID.In
(
     emp.Query.SubSelect(cust.Query.Location == "Indianapolis");
)
emp.Query.Load();


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

posted on Sunday, February 25, 2007 8:06:30 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]
 Wednesday, October 04, 2006

FOR IMMEDIATE RELEASE

Contact:sales@entityspaces.net

EntitySpaces 1.5 has been released with support for Hierarchical Data Models and LINQ.

The EntitySpaces architecture for .NET is a persistence layer and business object system for the Microsoft .NET 2.0 Framework.  EntitySpaces is database independent. The data providers are loosely coupled and allow you to use the same compiled code to access Microsoft SQL Server, Microsoft Access, Oracle, and MySQL, with VistaDB in the pipeline. EntitySpaces' business objects are generated from your database's metadata using MyGeneration, the highly downloaded, free code generator and OR Mapping tool.

EntitySpaces has in its ancestry the popular dOOdads architecture, and the same lead architect. Features include serialization, dynamic queries, saving via stored procedures or dynamic SQL, transactions, and more. The templates included will generate business classes, ASP.NET Admin Grids, and DotNetNuke Admin Grids. Source code is available. EntitySpaces targets both ASP.NET and Windows.Forms projects. DotNetNuke module developers will find it to be an attractive alternative to the DotNetNuke DAL.

EntitySpaces, LLC founding members include Mike Griffin, President and originating architect, Scott Schecter, and David Parsons. The team has a diverse background in technology solutions spanning more than 20 years. EntitySpaces is dedicated to providing affordable, easy-to-use, feature-rich developer tools with stellar support. Details, documentation, and a free, 45-day Trial Version may be found at:

http://www.entityspaces.net

# # #

posted on Wednesday, October 04, 2006 12:56:07 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Thursday, August 31, 2006

Welcome to the EntitySpaces 1.5.0 Beta
EntitySpaces Goes Hierarchical ....

The beta is actually pretty solid. However, it is versioned 1.4.3 and available to customers only until the official 1.5.0 is released.

These are our recommendations. Be sure to close MyGeneration and any of your Visual Studio solutions before installing.

  • We recommend you install right over the top of your current 1.4.2 release. You can always reinstall the 1.4.2 release if you need to.
  • Regenerate your Generated Templates using the "Generated Classes Master" template.
  • Next run the "EntitySpaces - Hierarchical" template, this will be located in the EntitySpaces->C#/VB->Generated namespace in the MyGeneration Template Browser. Select all of the tables in your database and generate.  This will create a new file called "EmployeeHierarchical.cs" or "EmployeeHierarchical.vb" for a table named Employee. Include these files in your solution, they should be generated into your generated folder with the rest of your classes.
  • Recompile and run ...

There is a new template you can experiment with in the EntitySpaces->esPlugIn namespace named EntitySpaces - Set esPlugin Settings.  You can use this template to override the default setting for EntitySpaces. You will find this very useful to experiment with the naming conventions for the Hierarchical objects, see what you can come up with. Be sure to post any very good settings, we might adopt them as our shipping defaults.

The Basic Tab


The Hierarchical Tab



You can change these settings and regenerate classes and see the effect, just hit OK to save your changes.

In the next BETA release you will not have to run the EntitySpaces - Hierarchical template separately, it will be included in the master and there will be a checkbox to indicate whether or not you want to generated hierarchical code or not.

Release Notes

  • Hierarchical support (C# and VB)
  • Both VB.NET and C# now support the new LINQ query syntax
  • Added CommandTimeout to the EntitySpaces config settings
    <add name="SQLDynamicTest" 
      providerMetadataKey="esDefault" 
      sqlAccessType="DynamicSQL" 
      provider="EntitySpaces.SqlClientProvider" 
      providerClass="DataProvider" 
      connectionString="Password=yadda" 
      commandTimeout="90" 
      databaseVersion="2005" />
  • Implemented dOOdads QuerySource trick 
    // Read from a view, save to the core table
    EmployeeCollection empColl = new EmployeeCollection();
    empColl.Query.es.QuerySource = "vEmployee";  // This is a view
    empColl.Query.Load();
    
    Employee emp = empColl[0] as Employee;
    emp.LastName = "ViewsRock";
    empColl.Save();
  • New template for esPlugin settings including hierarchical settings (shown earlier)
  • Added DetatchEntity/AttachEntity to esEntityCollection
  • Add MarkAllColumnsAsDirty to help move records from one database to another
  • Fixed template bug that generated an invalid comment when it contained a double-quote (")
  • The esEntity.Collection property is now public
  • Increased the performance of our Save() logic
  • esEntityCollection.IsDirty was incorrectly reporting true after Save, fixed
  • Added public class to each provider to fix Visual Studio designer bug

Not in this BETA Version

  • Caching
  • AddNew fix, esEntityCollection.AddNew should call esEntity.AddNew
  • Many other enhancements will make it in before the final release.

We need your input and mileage on this. Normally, our internal testing which is pretty extensive is enough for us to cut a new build, however, this is a major set of new functionality.

- The EntitySpaces Team

 


posted on Thursday, August 31, 2006 8:23:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Tuesday, August 01, 2006

EntitySpaces 1.4.2

We have accumulated enough fixed and tested issues that we thought it was important to put out a maintenance release. The new downloads should be posted on Friday, August 4, 2006. We will announce their availability in the forums, once they are up. The following issues are addressed in this version:

  • Change Guid with default newid() to accept input for Saves for Microsoft SQL Server.
  • Add XML comment to LoadByPrimaryKey that warns if the template is run on a table with no primary key.
  • Trim invalid characters from aliases in esPlugin.
  • Add preliminary LINQ support.
  • AddNew rolls back for MySQL provider without error with InnoDb tables.
  • Error in MySQL stored procedure template comment if all fields are in the primary key.
  • IndexOutOfRangeException if the primary key(s) is(are) not the first column(s) in a table.
  • ASPX page template ignores Namespace.
  • Adding fks broke WebServices' serialization.
  • Do not over-write files when generating Custom Master classes.
  • Add using System.ComponentModel when not generating a single file.
  • Multi-line default values not generated correctly.
  • Remove Query.Load("OR") from compiled help and document Query.es.DefaultConjunction instead.
    The default conjunction for Query.Load() is "AND". You can change that with this:
    emps.Query.es.DefaultConjunction = esConjunction.Or;
    
  • Add QueryReset to Entities and EntityCollections.
    TestCollection collection = new TestCollection();
    
    // Get the LastName for active employees
    collection.Query.Select(collection.Query.LastName);
    collection.Query.Where(collection.Query.IsActive == true);
    collection.Query.Load();
    Assert.AreEqual(16, collection.Count);
    
    // These get added to the above.
    // Now we get LastName, FirstName
    // For active employees named "Costner"
    collection.Query.Select(collection.Query.FirstName);
    collection.Query.Where(collection.Query.LastName == "Costner");
    collection.Query.Load();
    Assert.AreEqual(3, collection.Count);
    
    // Reset the query and return all columns and all rows
    collection.QueryReset();
    collection.Query.Load();
    Assert.AreEqual(30, collection.Count);
    
  • Add Scale and Precision to esParameter for output parameters.
    public partial class AggregateTestCollection : esAggregateTestCollection
    {
        public void TestParamsWithScale()
        {
            esParameter myParam = new esParameter("Salary", 12.34);
            myParam.DbType = DbType.Decimal;
            myParam.Precision = 18;
            myParam.Scale = 2;
            myParam.Direction = esParameterDirection.Output;
    
            esParameters parms = new esParameters();
            parms.Add(myParam);
            parms.Add("FirstName", "Entity");
            parms.Add("LastName", "Spaces");
            this.ExecuteNonExec(esQueryType.StoredProcedure, "proc_esTestInsert", parms);
        }
    }
    

EntitySpaces 1.5

We have rescheduled the 1.5 release for the end of August. We understand that this delay is making it difficult, if not impossible, to fully evaluate the product. Installing the 1.4.2 maintenance release will assure that your Trial period does not run out before 1.5 is released. We are especially concerned for our existing customers who are counting on hierarchical support. But, we feel that meeting quality standards takes precedence over meeting deadlines. We will not release something with known bugs and "fix it as we go." When it is ready, 1.5 will be released only to our current customers as a Beta version. A Final version will be released for download by our customers, and as a Trial version to the general public, after we have received sufficient feedback, can be comfortable that it has been tested in a wide variety of environments, and have fixed any hidden issues. We appreciate your patience and believe it will be well rewarded, as the hierarchical API is shaping up very nicely.

  • Hierarchical support
  • Caching

Future Enhancements

We have not forgotten the other features requested. In fact, we are using a new issue tracking system that helps us keep tabs on over sixty items, from ObjectDataSource support to updateable Views. Rather than try to predict when these will be ready, our focus is on putting out a top-notch hierarchical release. As we get closer to delivering it, we will prioritize what we have and post a roadmap for 1.6 and beyond. The new system has already reduced the amount of administrative time we spend on tracking bugs and enhancements. That means more time is available to actually code on them :-)

The EntitySpaces Team

posted on Tuesday, August 01, 2006 1:21:27 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, June 18, 2006

[Upated September 30, 2006]

At first glance one might think that the new LINQ technology is a direct competitor to the EntitySpaces architecture; however that would not be a correct assumption. The LINQ Project is a codename for a set of extensions to the .NET Framework that encompass language-integrated query, set, and transform operations. It extends C# and Visual Basic with native language syntax for queries and provides class libraries to take advantage of these capabilities. EntitySpaces LLC has added the ability to use the LINQ syntax against EntitySpaces collections as of our 1.5 release.

As LINQ nears its official release we will look at translating the LINQ IQueryable<T> expression trees into our query API. In fact, when LINQ is first released it will support SQL Server only and rumor has it that LINQ is still a year or more out though Microsoft hasn't stated a release date yet. 

Have a look at this example: 

EmployeesCollection coll = new EmployeesCollection ();
coll.LoadAll();
// All employees with "i" in the last name ordered by FirstName in decending order
var emps = from e in coll
where e.LastName.Contains("i") orderby e.FirstName descending select e; foreach(Employees emp in emps) { Console.WriteLine(emp .FirstName + ", " + emp.LastName); }

It is even possible to derive your own result sets via the LINQ query against an EntitySpaces collection.


EmployeesCollection coll = new EmployeesCollection();
coll.LoadAll();

// All employees with "i" in the last name ordered by FirstName in decending order
var emps = from e in coll
                where e.LastName.Contains("i") 

                orderby
e.FirstName descending
                select
new { e.FirstName, e.LastName };

foreach(var dude in emps)
{
    Console.WriteLine(dude.FirstName + ", " + dude.LastName);
}

Some links you'll find useful:
Using LINQ with ASP.NET   (Part 1)
Using DLINQ with ASP.NET (Part 2)

posted on Sunday, June 18, 2006 12:47:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]