Friday, January 29, 2010

Here is a snapshot of EntitySpaces 2010 browsing a SQLite database. It’s not complete yet, we need to add the indexes and foreign keys but the metadata provider should be done by the end of this weekend. This is the code generation meta data provider. We still need to create the EntitySpaces data provider (which your SQLite application would use) but things are moving quickly.

SQLite_Metadata

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/WCF 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 Friday, January 29, 2010 11:39:54 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]
 Sunday, January 24, 2010

We are making our code generation architecture much more user friendly for those that would like to write custom templates, Here is an example of the changes we are making.

Old Way: (where “col” is an IColumn such as when you are looping through all of the columns in a table or view)

<%= esMeta.esPlugIn.PropertyName(col) %>

New Way:

<%= col.PropertyName %>

The old way still works of course. We will be using this new approach in our templates, it sure makes the templates easier to read and understand. The PropertyName property is still driven by your choices in the EntitySpaces “Settings” tab. We will be doing this for about 30 or 40 such “things” including the EntityName, CollectionName, ParameterName, QueryName, ProxyName, and so on in our code generation engine. We are making these changes to encourage more customer driven template development to accommodate our soon to come online template sharing library as well as making our own template development easier. Of course, there will be a help file available 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/WCF 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 Sunday, January 24, 2010 3:08:02 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, January 23, 2010

First, before we begin this blog post we wanted to let you know that we have re-enabled the commenting feature on our blog. Secondly, EntitySpaces 2009 already supports these SQL Server2008 data types but it returns them as type “string”. EntitySpaces 2010 allows you to handle them natively.

EntitySpaces has very powerful provider independence support so we have to be careful when implementing “extended” types for a given database engine. For instance, our NUnit test suite is a single binary that runs against all of our supported databases. The only thing we change when targeting a different database engine is the connection string, we don’t have to recompile or regenerate the code for each database because the databases all have essentially the same schema. So the question is, how do we handle non standard types offered by various database vendors? By non standard types we mean types that do not map to a .NET System Type such as System.Int32. We have the solution all worked out and EntitySpaces 2010 will allow us to support non-standard types offered by various database vendors. For instance, Microsoft SQL Server 2008 supports these types which require a separate assembly to work with.

Native SQL Type

.NET Type

geography SqlGeography
geometry SqlGeometry
hierarchyid SqlHierarchyId


The .NET types such as SqlGeography are contained in the Microsoft.SqlServer.Type assembly. Obviously we cannot link this library into or core EntitySpaces assemblies as this would require all EntitySpaces customers to have this assembly present even if they were only using Oracle. The good news is we have a solution for this. Here are the language mappings from the ES2010 esLanguages.xml file for the new SQL Server 2008 data types (currently, in ES2009 these map to type “string”, but now we map them to the real extended type).

<Type From="geography" To="SqlGeography" NonSystemType="true"/>
<Type From="geometry" To="SqlGeometry" NonSystemType="true"/>
<Type From="hierarchyid" To="SqlHierarchyId" NonSystemType="true"/>       

Notice that these are marked as NonSystemTypes = “true”, that is to say they cannot be mapped to a standard .NET type such as a “System.Int32” and so on …

During the code generation process we use this flag to generate the properties using the GetSystemObject/SetSystemObject methods as shown below.

virtual public SqlGeography TheGeography
{
    get
    {
        return (SqlGeography)base.GetSystemObject(MasterTypesMetadata.ColumnNames.TheGeography);
    }
    set
    {
        if(base.SetSystemObject(MasterTypesMetadata.ColumnNames.TheGeography, value));
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(MasterTypesMetadata.PropertyNames.TheGeography));
            }
        }
    }
}   

Notice how we simply use GetSystemObject/SetSystemObject and then cast to the specific type. This is done in your generated classes and not in our core assemblies. The property shown below is a standard column that maps to a system type (an integer column) and thus uses GetSystemInt32/SetSystemInt32 and requires no cast.

virtual public System.Int32? TheInt
{
    get
    {
        return base.GetSystemInt32(MasterTypesMetadata.ColumnNames.TheInt);
    }
    set
    {
        if(base.SetSystemInt32(MasterTypesMetadata.ColumnNames.TheInt, value))
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(MasterTypesMetadata.PropertyNames.TheInt));
            }
        }
    }
}   

Since we cannot have a GetSystemSqlGeometry() in our core assemblies without linking to special database provider assembly this works out nicely. It doesn’t effect non Microsoft folks at all.

An Example

Take a look at this rather sophisticated example. Here we create a complex shape and store it to the database. We have created a table in SQL Server 2008 called “MasterTypes” that we are using for testing all possible types.

SqlGeometryBuilder gb = new SqlGeometryBuilder();

// Set the Spatial Reference ID to 1
gb.SetSrid(1);
// Start the collection
gb.BeginGeometry(OpenGisGeometryType.MultiPolygon);
// Start the first element in this collection
gb.BeginGeometry(OpenGisGeometryType.Polygon);
// Define the first element (figure)
gb.BeginFigure(-77.054700,38.872957);
gb.AddLine(-77.057962, 38.872620);
gb.AddLine(-77.058547, 38.870079);
gb.AddLine(-77.055592, 38.868840);
gb.AddLine(-77.053217, 38.870656);
gb.AddLine(-77.054700, 38.872957);
// End the first element (figure)
gb.EndFigure();
// Define the second figure
gb.BeginFigure(-77.056972, 38.870639);
gb.AddLine(-77.055851, 38.870219);
gb.AddLine(-77.054875, 38.870864);
gb.AddLine(-77.055452, 38.871804);
gb.AddLine(-77.056784, 38.871655);
gb.AddLine(-77.056972, 38.870639);
gb.EndFigure();
// End the first polygon
gb.EndGeometry();

// Define the second polygon
gb.BeginGeometry(OpenGisGeometryType.Polygon);
gb.BeginFigure(-77.056408, 38.875290);
gb.AddLine(-77.056947, 38.875224);
gb.AddLine(-77.057466, 38.873598);
gb.AddLine(-77.057273, 38.872737);
gb.AddLine(-77.055335, 38.873020);
gb.AddLine(-77.055499, 38.874058);
gb.AddLine(-77.056408, 38.875290);
gb.EndFigure();
gb.EndGeometry();
// End (close) the collection

gb.EndGeometry();

MasterTypes m = new MasterTypes();
m.TheGeometry = gb.ConstructedGeometry;
m.Save();

This code works prefectly and saves complex shape to the database. Of course, you can read it back and access the "TheGeometry” property (we named the database column ‘TheGeometry’).

The screen shot below is what it looks like in the debugger when we inspect our “TheGeometry” property after reading it back from the database.

TheGeometry

One thing we have decided on is whether we should always make these extended types as nullable types, the answer will probably be yes.

We are also looking at supporting the SqlFileStream functionality but that is a little more complex. This approach should allow us to support non-standard data types for other database systems 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/WCF 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 Saturday, January 23, 2010 11:21:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Thursday, January 21, 2010
Now having looked at the video this morning I promise not to make a video at 1 in the morning when I can barely hold my head up. I'm buying a professional quality microphone and will make video's in the morning after a fresh cup of coffee, still, the proxies are very cool ...

This preview should really get you fired up for ES2010. Our proxies are now even smarter. In EntitySpaces 2009 (ES2009) our proxies track row state for you automatically which is cool, however in ES2010 they also track column level dirty information. The proxies can also be decorated with DataContract, XML, and JSon serialization attribute tags all at the same time. This is very cool for client side proxies as clients can then serialize the data to disk, or to the Browser, or simply change the data and send it back to the server.

Our client side proxies are also great candidates for MVC development. With the coming release of .NET 4.0 you will have WCF and Workflow (WF4) integration capabilities and our client side proxies will make great data envelopes for traveling around inside of WF4 and ensure that your row state and column level dirty information are always up-to-date. We are making sure EntitySpaces can go where ever you need to go and do so effortlessly, and this includes the Cloud (more on that in an upcoming preview).

Our next preview video will show you ES2010’s ability to generate your WCF endpoints automatically. You can generate all of your WCF end points for your data in one big “mombo” WCF Service or have each entity type housed in it’s own WCF Service. This EntitySpaces template is highly customizable as well since it does not generate the core classes. It merely creates WCF Services and you can tweak it to meet your specific needs. Also, we are adding an online sharable template library that is accessible from within the EntitySpaces Visual Studio AddIn. That means you can upload and download templates directly from the template browser. So, if you create a cool tweak to our WCF template or create an awesome REST template for EntitySpaces and you want to share it you can, and it will automatically show up in the EntitySpaces Template Browser for all EntitySpaces users. Are you excited yet?

Take a look at this preview and see what you think.

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/WCF 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, January 21, 2010 12:40:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Monday, January 11, 2010
video

In this video we take a quick look at enhancements to Extended Properties (custom properties you add manually to your entities) and the ability to Clone both collections and single entities. The clones are shallow clones, that is to say, they do not clone the entire hierarchical model.

To watch the video click HERE or on the image on the left …

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/WCF 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, January 11, 2010 7:45:46 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, January 03, 2010
video

Click the link above to watch the video …

This is another quick progress video on EntitySpaces 2010. In this video we show off our esEntityCollectionView<> class which in ES2009 relied on ADO.NET DataViews. However, these are now entirely our own creation and far superior. Remember, we do not use ADO.NET under the hood anymore (see Part I here if you missed it). However, our data providers which read and write to the database of course.

Also, we show off some very cool new debugging features that will really help you when debugging your EntitySpaces applications. And finally, with the use of implicit type casting operators, working with the proxy stub classes has become basically, well, transparent.

For instance, this is now possible … (and more)

public EmployeesCollectionProxyStub GetEmployees(string serializedQuery)
{
    EmployeesCollection coll = new EmployeesCollection ();
    coll.LoadAll();

    return coll;  // But where's the creation of the proxy stub collection?
}

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/WCF 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 Sunday, January 03, 2010 8:16:37 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, December 26, 2009

videoWe are furiously working on our ES2010 Prototype which is quickly turning into the “real deal”. The first thing we wanted to address was performance and have squeezed out a ton more horsepower, the performance is excellent. Secondly, we wanted to enhance our collections by implementing IList<T> which we have done. There is no longer a need to convert our collection classes to List<T> collections to gain access to it’s powerful API. Our collections and List<T> are essentially one and the same.

This means you have a whole new set of functionality at your disposal (using the newer .NET syntax) on our collections, including filtering, which is shown in the (hastily put together) video, you can view the video by clicking on the image on the left.

Here’s the way you can filter a collection in ES2010. The “coll” variable is an EntitySpaces collection object.

coll.Filter = coll.AsQueryable().Where(d => d.FirstName.EndsWith("2")).OrderByDescending(d => d.FirstName); 

In this case we are filtering an EntitiySpaces collection so that it only shows only FirstName’s that end with the number “2” and we also sort them in descending order by FirstName as well.

You can also now perform operations like this (shown below) on your collections, granted this example doesn’t make much sense but it does show the functionality.

int? max = coll.Max(ent => ent.EmployeeID); // Find the highest EmployeeID

We are working very hard and preserving the API too. One of the main changes is that we now no longer use DataTables/DataRows under the hood as a storage mechanism, however you really shouldn’t notice that. Our Custom Property support will now be attribute based and extremely simple to use. Serialization is going to even better (and it’s already fantastic in ES2009). Binary serialization will now be tiny now that we no longer use DataTable’s and we will be adding full JSON serialization support as well. There is just so much more to come and we can’t wait to show you more.

Forgive this hastily put together video, we will be doing a series of these video’s so keep your eyes on the blog.

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/WCF 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 Saturday, December 26, 2009 8:15:59 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Saturday, December 12, 2009

This is our final release for ES2009, the version number is 2009.2.1214.0. The Developer version and Source Version are available now. The trial version is now available as well. Watch for an announcement on our twitter account if you are waiting on the new Trial version.

Release Notes:

  • The DynamicQuery API “Between” bug has been fixed.
  • The VB.NET Hierarchical Model Equals vs IsNot bug has been fixed.
  • All SQL CE providers now correctly support the SQL TOP syntax.
  • There was a bug that would sometimes occur in the Microsoft SQL Contains clause. This has been fixed.
  • We tweaked the IDataErorrInfo so that it shouldn’t matter if column names or property names are passed in.
  • Modified SqlClientProvider.Shared.BuildDynamicInsertCommand to ignore modifications to dis-allowed columns, such as Computed, Concurrency, and AutoIncrement.
  • Added a mapping entry for the Microsoft SQL HierarchyId data type.
  • Added an overload for SetColumn() which should be used when setting the values of virtual properties that exist in the underlying DataTable. The usage is covered in this blog post. We plan to make big improvements our virtual column handling in ES2010. The signature is as follows, you pass in true as the last parameter for virtual properties.

          public void SetColumn(string columnName, object Value, bool isVirtualColumn)
  • Greatly improved our Schema/Catalog handling in the DynamicQuery API making cross schema/catalog joins much better now.
  • During an insert all columns that are either computed or that have defaults are now returned (currently only implemented for Microsoft SQL Server). We will revisit this for all providers in ES2010.
  • Greatly improved the power of the ON clause of a JOIN statement. The ON clause can now fully parse anything that can be used in a Where clause. This means the full Where syntax can now be used in the ON clause of a JOIN statement. This is true for all providers accept for Microsoft Access which requires extra parenthesis be paced around each join condition. We will revisit this functionality for MS Access in ES2010.
  • Due to our relocation to a new dedicated hosting server some of our links on the Windows “EntitySpaces 2009” menu were no longer valid. This was also true for “Forums” link on the “Whats New” tab, these have been fixed.
  • Added WithNoLock support. This is currently support for Microsoft SQL Server only (Locking hints are vastly different on all database systems).

    OrderQuery oq = new OrderQuery("o");
    OrderItemQuery oiq = new OrderItemQuery("oi");

    oq.Select(oq.CustID, oq.OrderDate, "<sub.OrderTotal>");
    oq.From
        (
            oiq.Select(oiq.OrderID,
                (oiq.UnitPrice * oiq.Quantity).Sum().As("OrderTotal"))
                .GroupBy(oiq.OrderID)
        ).As("sub");
    oq.InnerJoin(oq).On(oq.OrderID == oiq.OrderID);

    OrderCollection collection = new OrderCollection();
    oq.es.WithNoLock = true; // <== NEW
    collection.Load(oq);

    Notice that even though many query objects are being used you only need to set WithNoLock to true for the parent or main query object. The SQL generated is as follows:

    SELECT o.[CustID],o.[OrderDate],sub.OrderTotal 
    FROM
    (
       SELECT oi.[OrderID],SUM((oi.[UnitPrice]*oi.[Quantity])) AS 'OrderTotal' 
       FROM [OrderItem] oi WITH (NOLOCK)
       GROUP BY oi.[OrderID]
    ) AS sub
    INNER JOIN [Order] o WITH (NOLOCK)
    ON o.[OrderID] = sub.[OrderID]
     

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/WCF 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 Saturday, December 12, 2009 2:47:24 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Sunday, December 06, 2009

This question has been brought up recently so we created a sample to demonstrate how this can be accomplished. When we refer to Virtual Properties we mean properties that you manually add to your Custom classes (as opposed those that are created from your database schema during code generation and wind up in your generated classes). In this example we are going to create two Virtual Properties, one that is backed by a private string variable and the other backed by a column in the underlying DataTable.

Adding the Virtual Properties to the Custom Class (Your Main Entity)

Notice the two properties MyCustomProperty and MyCustomPropertyFullName

namespace BusinessObjects
{
    public partial class Employees : esEmployees
    {
        // Virtual Property backed by a private string
        public string MyCustomProperty
        {
            get { return myCustomProperty; }
            set { myCustomProperty = value; }
        }
        private string myCustomProperty;

        // Virtual Property backed by a Column in the underlying DataTable
        public string MyCustomPropertyFullName
        {
            get { return this.GetSystemString("FullName"); }
            set { this.SetColumn("FullName", value, true); } // New Method
        }

        // Makes sure these properties show up when binding ...
        protected override List<esPropertyDescriptor> GetLocalBindingProperties()
        {
            List<esPropertyDescriptor> props = new List<esPropertyDescriptor>();

            props.Add(new esPropertyDescriptor(this, "MyCustomProperty", typeof(string)));
            props.Add(new esPropertyDescriptor(this, "MyCustomPropertyFullName", typeof(string)));

            return props;
        }

        // We need to do this for the deserialization process (more on this later)
        public override void AddNew()
        {

            // only needed if for the DataTable backed column
            base.AddNew();

            if (!this.Table.Columns.Contains("FullName"))
            {
                this.Table.Columns.Add("FullName", typeof(System.String));
            }
        }

    }
}

Typically, you don’t allow users edit virtual properties. In this example we are allowing it and this is the reason we needed to override AddNew. The reason we need to do this is that when we deserialize from the client back to the server you do not get to create the EmployeesCollection, instead the deserialization process does this. So, we overload AddNew() to make sure our underlying DataTable contains the DataColumn to hold our “FullName” value coming back from the client side. In ES2010 we are going to take a hard look at this and make this area easier. With all of the new emphasis on Silverlight 4.0 we want to make sure our proxies and serialization logic are the best and easiest they can be. However, if you are not going to allow users to edit “Virtual Properties” on the client there is no need to override AddNew.

The above code in “red” is new and will be the next maintenance release. The allows you to set virtual columns in the DataTable and not have them marked as dirty which causes the provider to try to save it. However, you can do this now without the new method though the code for that is not shown here.

Adding the Virtual Properties to the Proxies

The Server Side Proxy Class

When we generated the server and client proxies we made sure to check the “CompactXml” checkbox. This makes the XML sent over the wire much more compact. Our “Compact Xml” names each field a0, a1, a2 and so on (in the XML only). This makes the XML so much smaller than using the actual property names. However, it doesn’t effect your property names whatsoever, you still always work with your nice names in code. We recommend that you start your Virtual Properties at “a1000” and then you will never get into to trouble, that is, unless you have 1000 columns in your table in which case you probably have bigger problems.

Our server side and client side proxies are partial classes, so you can easily add more properties to them. Below is the server proxy partial class that we created to house our two addition properties. This ensures that you never hand edit the generated proxies.

namespace BusinessObjects
{
    public partial class EmployeesProxyStub
    {
        [DataMember(Name = "a1000", Order = 1000, EmitDefaultValue = false)]
        public System.String MyCustomProperty
        {
            get
            {
                return this.Entity.MyCustomProperty;
            }
            set { this.Entity.MyCustomProperty = value; }
        }

        [DataMember(Name = "a1001", Order = 1001, EmitDefaultValue = false)]
        public System.String MyCustomPropertyFullName
        {
            get
            {
                return this.Entity.MyCustomPropertyFullName;
            }
            set { this.Entity.MyCustomPropertyFullName = value; }
        }
    }
}

The Client Side Proxy Class

If you are deserializing from the server side proxies into the client side proxies you want to use the same signature for the the properties in the client side proxy.

namespace Proxies
{
    public partial class EmployeesProxyStub
    {
        [DataMember(Name = "a1000", Order = 1000, EmitDefaultValue = false)]
        public System.String MyCustomProperty
        {
            get
            {
                return _myCustomProperty;
            }
            set
            {
                this.SetDirty();
                this._myCustomProperty = value;
                this.RaisePropertyChanged("MyCustomProperty");
            }
        }
        private System.String _myCustomProperty;

        [DataMember(Name = "a1001", Order = 1001, EmitDefaultValue = false)]
        public System.String MyCustomPropertyFullName
        {
            get
            {
                return _myCustomPropertyFullName;
            }
            set
            {
                this.SetDirty();
                this._myCustomPropertyFullName = value;
                this.RaisePropertyChanged("MyCustomPropertyFullName");
            }
        }
        private System.String _myCustomPropertyFullName;
    }
}

One Minor Gotcha

The way our logic is setup the esRowState property of the proxies must be the last property serialized because it determines the row state. Therefore, what we did for this example was to hand edit both the generated proxies (server and client) and change the esRowState to the name and order of 10,000 to make sure it’s last. Here are the hand edits …

[DataMember(Name = "a10000", Order = 10000)]
public string esRowState
{
    get { return this._esRowState; }
    set { this._esRowState = value; }
}

However, we have already made changes in our template(s) so that our next maintenance release (due out very soon) will always set the esRowState to the name and order of 10,000. If you want to make these hand edits to your templates you can do so very easily and simply regenerate. You would need to do this in both proxy templates if you are using both the server and client proxies.

BEFORE

<%if(WcfSupport){%>[DataMember(Name="<%=CompactXML ? "a" + compactXmlIndex++.ToString() : "esRowState"%>"<%if(WcfOrder){%>, Order=<%=(++lastOrdinal).ToString()%><%}%>)]<%}%>
public string esRowState
{
    get { return TheRowState;  }
    set { TheRowState = value; }
}<%}%>

 

AFTER

<%if(WcfSupport){%>[DataMember(Name="<%=CompactXML ? "a10000" : "esRowState"%>"<%if(WcfOrder){%>, Order=10000<%}%>)]<%}%>
public string esRowState
{
    get { return TheRowState;  }
    set { TheRowState = value; }
}<%}%>

 

Finally, the test, does it work?

First, this code is for demonstration purposes only. You never have to use our esDataContractSerializer manually, in fact, you should not be using it unless you absolutely have to. Instead, just pass our proxies to and from your WCF methods as normal parameters and the serialization will happen normally. However, the code below uses our esDataContractSerializer so you can try this in your own code quickly without having to build the services and test it all. In this example we serialize from the server proxies (found in your generated classes) to the client side proxies and back again. If you were using the server proxies on both sides of the conversation you wouldn’t need to generate or mess with the client side proxies of course.

It’s fun to run the code below and look at the XML that is sent back and forth.

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        EmployeesCollection coll = new EmployeesCollection();
        EmployeesQuery q = new EmployeesQuery("e");

        q.SelectAllExcept(q.Notes, q.Photo); // We want all columns but the Notes and Photo
        q.Select((q.LastName + ", " + q.FirstName).As("FullName"));  // Fills our DataTable backed property
        q.es.Top = 3;

        if (coll.Load(q))
        {

            // Change our string back properties
            foreach (Employees emp in coll)
            {
                emp.MyCustomProperty = "Test";
            }

            // Create Our Proxy Stubb
            BusinessObjects.EmployeesCollectionProxyStub server = new BusinessObjects.EmployeesCollectionProxyStub(coll, false);

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

            using (StreamWriter sw = File.CreateText("C:\\query.xml"))
            {
                sw.Write(xml);
                sw.Flush();
                sw.Close();
            }

            // Deserialize the string above into our Client side proxy
            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 = "CrazyDude";
            client.Collection[0].MyCustomProperty = "MyCustomProperty";
            client.Collection[0].MyCustomPropertyFullName = "Griffin, Mike";

            // Serialize our client side proxy into xml and send it to the server
            xml = esDataContractSerializer.ToXml(client);

            // Deserialize it on the server, 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();
        }
    }
    catch (Exception ex)
    {

    }
}

The XML

Notice that our two custom properties are at a1000, and a1001 and we have changed esRowState to be a10000.

<EmployeesCollection xmlns="http://tempuri.org/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Collection>
        <Employees>
          <a0>1</a0>
          <a1>CrazyDude</a1>
          <a2>AAAA</a2>
          <a3>Sales Representative</a3>
          <a4>Ms.</a4>
          <a5>1948-12-08T00:00:00</a5>
          <a6>1992-05-01T00:00:00</a6>
          <a8>Seattle</a8>
          <a9>WA</a9>
          <a10>78890</a10>
          <a11>USAa</a11>
          <a12>(206) 555-9857</a12>
          <a13>5467</a13>
          <a16>70272</a16>
          <a17>http://accweb/emmployees/davolio.bmp</a17>
          <a1000>Test</a1000>
          <a1001>CrazyDude, AAAA</a1001>
          <a10000>Unchanged</a10000>

        </Employees>
        <Employees>
          <a0>2</a0>
          <a1>Fuller</a1>
          <a2>tttt</a2>
          <a3>Vice President, Sales</a3>
          <a4>Ms.</a4>
          <a5>1953-02-19T00:00:00</a5>
          <a6>1992-08-14T00:08:00</a6>
          <a7>908 W. Capital Way</a7>
          <a8>Tacoma</a8>
          <a9>WA</a9>
          <a10>98401</a10>
          <a11>USA</a11>
          <a12>(206) 555-9482</a12>
          <a13>3457</a13>
          <a16>99</a16>
          <a17>http://accweb/emmployees/fuller.bmp</a17>
          <a1000>Test</a1000>
          <a1001>Fuller, tttt</a1001>
          <a10000>Unchanged</a10000>

        </Employees>
        <Employees>
          <a0>3</a0>
          <a1>Spaces</a1>
          <a2>tttt</a2>
          <a3>Sales Representative</a3>
          <a4>Ms.</a4>
          <a5>1963-08-30T00:00:00</a5>
          <a6>1992-04-01T00:00:00</a6>
          <a7>722 Moss Bay Blvd.</a7>
          <a8>Kirkland</a8>
          <a9>WA</a9>
          <a10>98032</a10>
          <a11>USA</a11>
          <a12>(206) 555-3412</a12>
          <a13>3355</a13>
          <a16>2</a16>
          <a17>http://accweb/emmployees/leverling.bmp</a17>
          <a1000>Test</a1000>
          <a1001>Spaces, tttt</a1001>
          <a10000>Unchanged</a10000>

        </Employees>
    </Collection>
</EmployeesCollection>

Summary

This was an extremely valuable exercise for us and revealed a few shortcomings when it comes to serialization virtual properties. Is is possible to implement your code without the new method in red above but that code is not shown here. We are hoping most of you desiring this functionality will be upgrading to our upcoming maintenance release. Also, remember, you can generate entities from views and in views you can create columns that are virtual and not based on database columns at all. This would make a lot of the above work a mute exercise with the caveat that views cannot be saved (easily) back to the database.

Our proxies are very important to future of EntitySpaces and they even run down inside the browser along with our DynamicQueries inside of Silverlight (under the browser) and we will be stepping back to see how we can make them far more powerful and easy to expand in ES2010. However, our next maintenance release will certainly make the above code a no brainer.

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/WCF 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 Sunday, December 06, 2009 2:53:37 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
 Wednesday, November 25, 2009

Last night we moved our site(s) over to dedicated hosting, there are a few kinds, very, very minor. We are working through those, but overall, things went incredibly well. The system is incredibly responsive. One of the main things you will see is that we are moving away from the Community Server forums and will be using the integrated DotNetNuke forums. The old forums are still available but will be made read only at some point in the near future. Click on the Forums link on our main menu to get to the new forums. There is an announcement post there.

Expect a more extensive blog post later on tonight …

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/WCF 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 Wednesday, November 25, 2009 7:55:15 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]