Tuesday, August 15, 2006

In anticipation of the hierarchical support to be released in EntitySpaces 1.5, we wanted to explain the relational object naming algorithm that we are using, what options will be available to you in the 1.5 release, and what we are planning for the future. We also would like your feedback on whether or not this implementation meets all your needs.

Your first question is probably, "What the heck is a relational object name, and why does it need an algorithm?" Take this code which will be possible using Northwind for example:

Employees emp = new Employees();
emp.LoadByPrimaryKey(1);

TerritoriesCollection terrColl = emp.Territories;

The first two lines are pretty routine. That last line does an awful lot for one line of code. That line traverses from an individual entity (Employees) through a many-to-many associative table (EmployeeTerritories - completely transparent) and retrieves a collection (TerritoriesCollection) of just the Territories related to that Employee. In EntitySpaces 1.4 there is no Territories object in the Employees entity class. The templates for EntitySpaces 1.5 will automatically generate a new object in the Employees class called Territories. "Territories" is the relational object name.

Your second question may be, "That seems pretty straight-forward. What's the big deal?" If you're a DBA or veteran coder that is familiar with complex databases, then you are already anticipating the problems that will arise if you need to generate unique names for all the relationships in a database. On the other end of the spectrum, you may be a programmer that understands parent and child relationships. You do not want to get a doctorate in hierarchical modeling. You just want relationships to work in your application. Out-of-the box, EntitySpaces 1.5, using the default settings, will generate hierarchical code that will work for 99.9% of real-world apps. It will be easy to use. And, it will offer some customization options to cover that additional 0.1% of the cases. This post is designed to give some insight into what the relational object names will be, how they will be generated, and why we chose that algorithm.

A Schema for Hierarchical Testing

Consider the tables and relationships in the schema diagram below. Most of you will recognize the similarity with Northwind. But, from a foreign key point of view, there are some significant differences. The schema is from the test database we are using for our hierarchical unit tests. It is specifically designed to stress test a full range of relationships and combinations of relationships. Here are some notable differences:

  1. Customer has a composite primary key, but it is not part of a many-to-many. We have better design choices today, but this situation is not uncommon in legacy databases.
  2. CustomerGroup links to Customer, but only uses part of Customer's composite primary key.
  3. Order links to Customer through a composite foreign key; CustID and CustSub.
  4. CustomerGroup and Group have a one-to-one relationship. This is unusual for a well normalized schema, but it is sometimes necessary. We have seen it in cases where a table ran up against a limitation in the database for the number of columns in a table. The columns had to be split into two tables with a one-to-one relationship.
  5. The self-referencing foreign key has been retained in the Employee table, but was renamed Supervisor instead of ReportsTo.
  6. There are two many-to-one foreign keys pointing from Customer to Employee; Manager and StaffAssigned. This is very common and tests possible naming ambiguity. If Customer had a relational object named Employee, you would not know which relationship it referred to.
  7. In the link between Order and Employee, the foreign column name is the same as the primary column name. This is quite common, and tests a possible point of naming collision.
  8. From a practical stand-point, there are two types of many-to-many relationships.
    • Simple cross-reference: This is illustrated by Employee - EmployeeTerritory - Territory. EmployeeTerritory has no user entered fields. The fields are all in the primary key. In this case, Employee will have a relational object named Territory and Territory will have a relational object called Employee. The EmployeeTerritory table is transparent in the EntitySpaces' hierarchical model. There are relational objects for EmployeeTerritory, but they are mainly there in case your schema changed (you added a non-key field to EmployeeTerritory) and it became a complex cross-reference.
    • Complex cross-reference: Order - OrderItem - Product is technically a many-to-many, but it has additional fields aside from the primary keys (e.g.; Quantity). EntitySpaces treats it as if it were two separate sets of relationships; Order - OrderItem and Product - OrderItem. The relational objects for both of these will be your primary working objects. We will show later how easy it is to access all the Product fields for each OrderItem of an Order. There is a relational object in Order named Product. But, again, it is primarily there to prevent break breaking changes during a regeneration of a changed schema.

 

Generated Relational Object Names

The table below contains the default names generated for each table above, the relationship it covers, and the return type. "Many To One" and "One To One" always return entities. "Zero To Many" and "Many To Many" always return collections. For the technically minded, there are dozens of combinations of cardinality, optionality, and direction which do not seem to be represented in the Relationship column. In reality, behind the scenes, EntitySpaces sub-groups everything into one of the four relevant categories it needs. And, to effectively use EntitySpaces you do not even need to be worried about those. They are pertinent to this discussion, but as a programmer, we will show later, how knowing the object you are in and the object you want to relate to, are the only two pieces of information you need to discover the power of hierarchical objects.

Table Relational Object Names Relationship Return Type
Employee CustomerAsStaffAssigned Zero To Many CustomerCollection
  CustomerAsManager Zero To Many CustomerCollection
  EmployeeAsSupervisorChildren Zero To Many EmployeeCollection
  EmployeeAsSupervisorParent Many To One Employee
  Territory Many To Many TerritoryCollection
  EmployeeTerritoryAsEmpID Zero To Many EmployeeTerritoryCollection
  OrderAsEmployeeID Zero To Many OrderCollection
Customer OrderAsCustID Zero To Many OrderCollection
  CustomerGroupAsCustomerID Many To One CustomerGroup
  EmployeeAsStaffAssigned Many To One Employee
  EmployeeAsManager Many To One Employee
Order OrderItemAsOrderID Zero To Many OrderItemCollection
  Product Many To Many ProductCollection
  CustomerAsCustID Many To One Customer
  EmployeeAsEmployeeID Many To One Employee
OrderItem OrderAsOrderID Many To One Order
  ProductAsProductID Many To One Product
Product OrderItemAsProductID Zero To Many OrderItemCollection
  Order Many To Many OrderCollection
Territory Employee Many To Many EmployeeCollection
  EmployeeTerritoryAsTerrID Zero To Many EmployeeTerritoryCollection
EmployeeTerritory EmployeeAsEmpID Many To One Employee
  TerritoryAsTerrID Many To One Territory
CustomerGroup CustomerAsCustomerID Zero To Many CustomerCollection
  Group One To One Group
Group CustomerGroup One To One CustomerGroup

 

Usage Example:

We have a collection of Orders (Lines 1 and 2 in the code below). We grab one (3). We need to change the CustomerName for the related Customer (5). We need to set the OrderDate (6). (Notice that we use the EntitySpaces' StringProperty (str) to convert the string to a date for us.) We want to set the UnitPrice for all the OrderItems related to this Order (7 - 13). The price we want to use is the base UnitPrice set in the Product file for the Product related to the OrderItem plus 10% (9, 10). We want to save all changes (14). This blog is about names, but that last line certainly deserves some special attention. "ord" is part of a collection ("ordColl") so we need to call save on the collection, not the entity. That one line saves the changed Customer, the changed Order, and all the changed OrderItems, and it is wrapped neatly in a transaction. Your changes commit or fail as a unit.

1    OrderCollection ordColl = new OrderCollection();
2    ordColl.LoadAll();
3    Order ord = ordColl.FindByPrimaryKey(11);
4   
5    ord.CustomerAsCustID.CustomerName = "Test";
6    ord.str.OrderDate = "1999-12-31";
7    foreach (OrderItem item in ord.OrderItemAsOrderID)
8    {
9        item.UnitPrice = item.ProductAsProductID.UnitPrice.Value
10          * (decimal)(1.1);
11       Console.WriteLine(item.ProductAsProductID.ProductName
12          + " - " + item.UnitPrice.Value.ToString());
13   }
14   ordColl.Save();

A detailed examination of what is going on is the subject of another blog post. What we are interested in is more practical. As we are entering code, how do we know the relational object names that apply? I do not want to memorize hundreds of relations in dozens of tables. I do not care if it is one-to-many or a many-to-one, I need to get the Customer related to an Order. And, I need to know whether I am dealing with an entity or a collection. How does EntitySpaces 1.5 make my life easier? The answer resides in Intellisense. If the objects are intelligently named, they will be easy to find. Once found, Intellisense shows you what it is, and it will be easy to use. That brings us to our next subject...

Why Those Names?

Our goals for the generated relational object names were much the same as the goals stated in most naming guidelines. Sometimes seeking one goal will be in conflict with another, and compromises have to be taken. The one rule that cannot be compromised is that the names must be unique within the namespace and class. If the code will not compile, there is not much sense in continuing. Beyond that, here is what we aimed to achieve:

  • Readability - The names cannot be so big and cumbersome that the code becomes un-readable.
  • Understandability - You should be able to see the name and understand its function in relation to the class that contains it.
  • Usability - Without intimate knowledge of the database structure, you should be able to find what you want in Intellisense and use it properly.
  • Portability - This usually refers to portability between languages, case-insensitive languages in particular. But, we already give you the option of using the VB templates. Because we are generating names, by portability we mean the algorithm, too, has to be portable to a wide variety of database schema and still create unique names.

Here are the default algorithms, starting with the simplest:

  • ForeignTableName - This is the simplest and clearest. In the very first piece of sample code at the start of the blog, you loaded an Employee. You know you need the territories for it, so next, in your IDE, you type "emp.ter". Intellisense pops up and you see "Territory". That looks good. Intellisense also shows that it is a TerritoryCollection. Now you know that you can foreach through it or bind it to a DataGridView. This algorithm only works for one-to-one and many-to-many. But, you do not need to worry about that.
  • ForeignTableName + "As" + ForeignColumnName - At line 5 of the code sample above, you want to change the related Customer's CustomerName. You type "ord.cus". Intellisense has popped up. You see "CustomerAsCustID". That must be it, but why not just "Customer"? That is because the algorithm used for one-to-many and many-to one has to account for multiple links between the same tables. Say, down the road, your database schema changed and an Order had a BillToCustomer and a ShipToCustomer. The column name is used as a tie breaker. This is seen in the ForeignKeyTest diagram with the two columns in Customer that are related to Employee. Intellisense shows you that both EmployeeAsStaffAssigned and EmployeeAsManager have return types of "Customer". This is another clue and also lets you know that they are entities. They can be treated like any other entity. The appended column names "StaffAssigned" and "Manager" let you choose the right object for your task.
    Let's look at the foreach in line 7. This falls under the same algorithm. You want to change each of the OrderItems related to the Order. You type "ord.ord" and see OrderItemsAsOrderID and that it returns an OrderItemCollection. Now you can loop through it like any other collection, but it will only touch those OrderItems that are related to "ord".
  • ForeignTableName + "As" + ForeignColumnName + "Parent"
  • ForeignTableName + "As" + ForeignColumnName + "Children" - These two work in tandem. They are necessary because of self-referencing foreign keys. The Supervisor column in Employee is both a one-to-many and a many-to-one on the same table. An additional tie breaker is needed. You type "emp.emp". Intellisense shows both EmployeeAsSupervisorChildren and EmployeeAsSupervisorParent. You need to make a decision. Fortunately, you have another piece of information in Intellisense. EmployeeAsSupervisorChildren is an EmployeeCollection, while EmployeeAsSupervisorParent is an Employee (a single entity). EmployeeAsSupervisorChildren is the collection of employees that this employee supervises. EmployeeAsSupervisorParent is the Employee (single entity) that supervises this employee. Your choice should be clear based on your intended use.

Notice that the ForeignTableName is always there and always first. That is the key to finding it in Intellisense. You end up with either a collection or entity of just the related rows. You use them like any other EntitySpaces BusinessObject. They are lazy-loaded. (Retrieving all Orders does not automatically load all related OrderItems, Customers, etc.) Plus, you get the benefits of transactional saves. In the schema above, you can traverse all the way down from an Employee through Customer, Order, OrderItem, and Product. Or, you can head up the other way from Product. This is all most developers will need most of the time. But, what about those rare instances when a generated name collides with a Property that already exists in the class? That brings us to the next subject...

Customizing the Generated Names

In most cases, the defaults will suffice. But, what if the compiler says you have duplicate names? Or, what if your organization has Domain Specific Language policies? When you run the EntitySpaces' hierarchical template, you are presented with a few new fields that give you some flexibility on the generated names.

The above image is from the EntitySpaces template UI for 1.5 which is currently in testing. It may change depending on your feedback from this post, but it shows the current defaults. "Table" and "Column" are derived from esPlugin "Entity" and "PropertyName", respectively. By default, this just trims illegal characters and PascalCases the foreign table and column names. The easiest way to get rid of compiler errors is to add a prefix. "Referenced" for One and "Referring" for Many will let you eliminate both suffixes. The disadvantage is that typing "emp.ord" is not going to find the Order object on an Employee entity. You will need to know to type "emp.ref". On the other hand, all referential objects will be lumped together in Intellisense. You may find it easier to deal with them that way.

A really easy way to get all hierarchical objects in one area is to add a simple prefix like "fk" or "hier". FxCop will hate this, since Hungarian notation is definitely out. But, if you feel it abides by the four naming goals listed earlier, and makes you more productive, then we say go for it. On a side note, if your table and column names conform to Microsoft's guidelines, the default names will pass FxCop's naming rules. But, remember, if you have a column named "CustomerID', then FxCop will complain and suggest "CustomerId". If the column is "CustId", then FxCop will grouse about "Cust" not being in its dictionary and suggests not using abbreviations. You could go through your database and change the offending column and table names. Or, you could decide that FxCop is just quibbling and it is safe to ignore those apparent violations. 

By default, the suffix is only appended to self-referencing foreign keys. This keeps the other names shorter. If you feel that a suffix would give the extra information you need to distinguish collections from entities, then removing the check will put the suffix on all generated names. It could, also, be used as another way to eliminate duplicate names for the compiler.

This is a good point to talk about our future plans for hierarchical naming. Imagine a template UI that displayed all the relationships and the default object names. It let you Alias any or all the names with something of your own choosing and remembered your choices. That is the goal for a future release. If you have played with the ASP.NET Admin Grid template, or checked out the PDF instructions for it, you know how convenient being able to see the columns and the related fields can be. The UI code needs to be ported over from that template, and we would ideally prefer an approach that did not require setting up one table at a time. But, once 1.5 is out, and we have coded, tested, and released the requested features promised for 1.6, we intend to devote some time to this.

We want your feedback.

Between us, we have thousands of man-hours of practical experience with database coding going back over 20 years. But, we still learn something new almost daily. We are hoping our customers and other forum members will share their experience and help shape EntitySpaces. We know that the relational object names we are using are a bit on the ugly side. But, that is the compromise we chose to reach the goals set out earlier. If anyone has suggestions for improving these, we will gladly consider them. You can post your comments here or in the forums. We eagerly await your response...

- The EntitySpaces Team

posted on Tuesday, August 15, 2006 10:37:59 PM (Eastern Standard Time, UTC-05:00)  #   
 Friday, August 04, 2006

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

Here is an overview of the features:

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

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

Files

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

Usage

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

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

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

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

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

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

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

Vasilis of Think of Design and Scott rolled out the new EntitySpaces site design, and branding over the weekend, and we must say that we are very pleased with the results. The Think of Design team carefully listened to the design features we wanted and made useful suggestions to help us achieve the best online experience possible for our users. We would also add their prices are very reasonable, if you are looking for a one of DNN design we can without a doubt recommend their services. However the thing that impressed us the most was the after delivery service of Vasilis. After delivering the skin, logo, source files, etc he wanted to be involved with the application of the new design to the site, and made adjustments to get it just right for us. Let us know what you think of the new design, and a very special thank you to the Think of Design Team from all of us at EntitySpaces, you all rock;)

posted on Thursday, August 03, 2006 9:11:12 PM (Eastern Standard Time, UTC-05:00)  #   
 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)  #   
 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)  #   
 Thursday, June 15, 2006

We have had some issues come up that we thought should not wait until 1.5 is released. This maintenance release should hold you over until then. The DataGridView binding issues were the toughest nut to crack. And, unfortunately, those changes will require you to regenerate the Generated Master for your classes.

NOTE: You must regenerate your generated classes with the Master Template

EntitySpaces - Release Notes for 1.4.1 

  • Added “Use Schema” checkbox to SQL Server Stored Procedures template. Default is un-checked (dbo).
  • Changed MySQL Stored Procedure template delimiters from $$ to //.
  • Changed the esEntityCollection.Item Property so that it is no longer obsolete.
  • Fixed SqlClientProvider so that AnsiString output parameters now have the correct size property for computed columns.
  • Fixed bug in QueryBuilder for all 4 providers. If a Like() expression was used in the Where() clause before an Equal(bool) expression, then the parameter type for the boolean was set to a string.
  • Added two protected Methods to esEntityCollection:
    • AssignPrimaryKeys - Assigns the underlying DataTable's 'PrimaryKey' data member using the primary keys as defined in the collection's associated esColumnMetadataCollection.
    • RemovePrimaryKeys - Removes the DataTable's 'PrimaryKey' information by setting it to null. Call this to undo AssignPrimaryKeys().
  • Added three Properties to esEntityCollection:
    • AllowEdit - Default is true. Setting this to false prevents the user from editing a row in a DataGridView.
    • AllowNew - Default is true. Setting this to false prevents the user from adding new rows in a DataGridView.
    • AllowDelete - Default is true. Setting this to false prevents the user from deleting rows in a DataGridView.
  • Fixed esEntityCollection IBindinglList AddNew, ApplySort, and esEntity BeginEdit, CancelEdit, EndEdit, AddNew. This fixes the editing or clicking around in a DataGridView bug.
  • Fixed an issue where Extended Properties were not being included in the collection if MultiProviderMode was set to true.
  • Fixed DeleteAll() so that it honors the Filter(). Only records matching the Filter criteria will be deleted.
  • Fixed a problem that ocurred if your PrimaryKey column was not the first column in the table metadata.
  • Added a specific Exception for when you call Save on an entity that is part of a collection. You must call Save on the collection.


EntitySpaces Trial Version: 

  • The SqlDemo has been replaced by a new and improved EntitySpacesDemo. A zipped version with the runtime references removed is available on the Documentation|Downloads page.


Documentation: 

  • Added entries in compiled help for the new methods and properties.


Note: See the Release Notes for 1.4.1 for detailed installation and upgrade insructions.

posted on Thursday, June 15, 2006 12:03:31 AM (Eastern Standard Time, UTC-05:00)  #   
 Monday, June 05, 2006

We have released the first version of our EntitySpaces Template Suite for ASP.NET. Try the DEMO

Here are the features:

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

Simply generate your ASPX pages. Add them to your solution. Finally, add these files to your project. (The templates are installed to the EntitySpaces.C#.Web and EntitySpaces.VB.Web folders in MyGeneration. The files below are under WebTemplates in your EntitySpaces program folder.)

  • es_stylesheet.css
  • question.gif
  • GridBase.cs  - C# projects only
  • GridBase.vb  - VB.NET projects only

Both the installer and the DEMO site are available for download to all who have purchased EntitySpaces. See the download menu on the main EntitySpaces site. This new template suite will not be in the trial version. These templates are intended to provide the ability to administer databases over the web. This chore is typically overlooked although it is really needed. Such admin screens can eat up quite a bit of development time and they are much easier to generate. Other than the row of buttons at the top the demo site is 100% generated, no hand coding was done.

These templates are not currently supported on the same level as the templates that generate the EntitySpaces classes. EntitySpaces will not be bogged down in supporting these or allow them to effect the timing of our 1.5 release which is fundamental to our long term strategy. That being said we will of course address issues over time and fix things as time allows.

See the PDF file that describes the template(s) PDF

posted on Monday, June 05, 2006 10:57:32 PM (Eastern Standard Time, UTC-05:00)  #   
 Sunday, June 04, 2006

We have taken our soon to be released ASPX template suite and generated a site against the Microsoft SQL Northwind database. Nothing you will see on this site was hand coded (except for the row of buttons at the top and the URL link at the bottom - both on our master page). The ASP.NET templates are pretty sophisticated and are style sheet driven so please don't get hung up on the color scheme. We realize you probably wouldn't use these pages as your actual website but the ASP.NET pages do provide a nice admin system that sys-admins can use to administer your database and that developers can use during development. They also act as a very nice reference on how to use EntitySpaces in an ASP.NET application.

The EntitySpaces ASP.NET templates support master pages (optional), use the new Multiview/View construct and the GridView, allow for sorting on the header columns, paging, sub grids, editing, searching, and more. We're only a matter of days until they are released at which point all customers will have access to the templates in the download area. The EntitySpaces ASP.NET templates will not be included in the trial version of EntitySpaces. The documentation and demo site of course will be open to everyone.

Take a look http://www.entityspaces.net/thedemo/Employees_admin.aspx

posted on Sunday, June 04, 2006 1:49:34 AM (Eastern Standard Time, UTC-05:00)  #   
 Tuesday, May 23, 2006

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

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