Thursday, March 29, 2007
Milos Business Objects and "Flexible Object Mapping"
The Milos Business Objects and Business Entities provide features that fall well into the "Flexible Object Mapping" category (see "Feature 1: Flexible object mapping" in this article).
- Tables and views mapping: the business objects support both tables and views as the main source behind it, by just specifying the name of the table or view in the MasterEntity property of the BusinessObject.
- Multi-table mapping: the MasterEntity is usually the main table or view behind the business object, and related tables (either child tables or lookup tables) can be retrieved by override the business object's LoadSecondaryTables method.
- Naming convention: the business objects and entities definitely provide that. For instance, a CustomerBusinessObject's MainEntity could be a "v_Customers" view on the database. The view columns are represented in a business entity by a friendly property; for instance, a "cust_fname" column would be exposed as a "FirstName" property on the business entity.
- Attibute mapping:
- Primary key: the primary key column is specified by setting the PrimaryKeyField property on the business object. The column is exposed through the business entity by means of the PK property (every entity inherits this property, which maps to whatever column has been specified by the PrimaryKeyField property). Currently only single-column keys are allowed.
- Auto generated columns: if the business object is set to use "auto-increment integer" primary keys, it handles retrieving the key created by the database. For other types of values generated by the database, they can be retrieved by simply reloading a business entity, which will bring down fresh data for the object.
- Read-only columns: read-only columns are implemented as properties on the business entity; such property only has a get method. If the value for the column is generated by the database, it'll be available for the entity as soon as it gets created.
- Required columns: required columns are specified by adding the EmptyFieldBusinessRule to the business object's BusinessRules collection.
- Validation: validation for the data handled by the business object is done by creating subclasses of the BusinessRule class, implementing the validation code, and then adding an instance of the class to the business object's BusinessRules collection.
- Formula Fields: a business entity can have any kind of property. A "formula field" could be a property on the entity, that only has a get method, and within the get method, it can perform anything that's needed (like combining values from other properties and/or values read from the object's internal state - by means of calling the entity's GetFieldValue method).
- Data type mapping: type mapping is implemented as a typical .NET conversion. If a value is stored in the database as an integer, but there's a need to expose it through the entity as a string, a property of type string is added to the business entity, and we perform the conversion when reading the data off the object's internal state (i.e., this.GetFieldValue("SomeField").ToString()), or when setting its value. Another example is when an image is stored as an "image" type on the database, but then exposed as a Bitmap object through the entity. This is all possible.
If you want more info about any of those items, email me, and I'll post another entry here with more details.
Posted @ 9:30 AM by Lassala, Claudio (firstname.lastname@example.org)
Tuesday, March 27, 2007
Milos and Object-Relational mapping (ORM) tools
Every once in a while we get asked whether Milos has ORM tools, or how does Milos fit with ORM. Recently I've run accross this article: Top 10 Must Have Features in O/R Mapping Tools. It's a good quick read to learn a little about ORM tools. As I was reading the article, I was mentally mapping the features mentioned in the article to how they're are (or are not) implemented in Milos, and figured some of those may not be as clear to Milos users out there.
Over the next days I'll be posting to this blog many entries where I'll take each one of those features and explain how they exist (or not) in Milos. Make sure you read the article first, and then keep tuned for the upcoming posts. ;)
Posted @ 10:33 AM by Lassala, Claudio (email@example.com)
Thursday, March 22, 2007
Removing Collection Items by Primary Key
Boy, we've had tons of small improvements lately, quite a few of which are worth blogging about. Here is another one: It is now easily possible to remove items from a business entitie's sub item collection by its primary key. Here is an example:
This works with all key types (Guids, ints, strings).
Posted @ 4:34 PM by Egger, Markus (firstname.lastname@example.org)
Wednesday, March 21, 2007
Checking Certain Types of Business Rules Only
The Verify() method on business objects and business entities now has a new overload which allows to check a certain type of business rule only:
Note that this checks all rules of the specified type, or rules derived from that type.
Posted @ 8:32 PM by Egger, Markus (email@example.com)
Wednesday, March 21, 2007
Minor Empty Field Business Rule Enhancement
The empty field (required field) business rule has been enhanced to also consider Guid.Empty as a missing field. (Empty guids are really all 0's, so they were previously not considered empty in this rule).
Also, a minor change has been made to make sure null-values and System.DBNull are detected as empty in all cases.
Posted @ 8:29 PM by Egger, Markus (firstname.lastname@example.org)
Wednesday, March 21, 2007
StringHelper.ToFile() and Encoding
The latest version of the StringHelper class now features and overload of the ToFile() method that supports the definition of encoding settings.
EPS.Utilities.StringHelper.ToFile(actual, "Test.txt", Encoding.Unicode);
The following example writes a string in the default Windows codepage:
EPS.Utilities.StringHelper.ToFile(actual, "Test.txt", Encoding.GetEncoding(1252));
If your international special characters do not come out write, then it is probably an encoding issue, which you can solve by specifying the encoding.
Posted @ 7:14 PM by Egger, Markus (email@example.com)
Wednesday, March 21, 2007
Unique Field Business Rule
The most recent version of Milos (2.1.10315.0) has a new standard business rule that is a real timesaver. The rule verifies field uniqueness within a data source (such as a data table). This of course was possible before, but it required more coding. Now it is a no-brainer.
Example: Let's say you have an items table with a SKU field, and you want to make sure the field is unique across the entire table. Such a rule can be set up by adding the following line of code to your business object (typically inside the Configure() method):
"SKU", "pk_item", "Items", "The field is not unique!"));
That's all that's needed.
This rule covers a single field only. If you have two fields that need to be verified, then simply add the same rule more than once. In that case, all the specified fields will be verified for uniqueness independently of each other. (A different scenario would be the verification that the combination of two or more fields is unique - such as "we need a unique combination of first name and last name" - such a scenario is not covered by this rule).
Note that this rule is different from the rule that was there previously, which verified uniqueness only within a single entity. That rule is still there as well and covers a slightly different scenario.
This rule works well in most scenarios. Note that there are potential logic issues in applications that support offline scenarios. In those scenarios, the field may verify as unique, but later, when multiple users sync back with the system, uniqueness may be violated, unless the rule is run again. This is not something we can handle generically. Individual applications have to trigger that logic individually.
Posted @ 6:10 PM by Egger, Markus (firstname.lastname@example.org)
Wednesday, March 21, 2007
EPS Developer Services - Convert SQL Command to Code improvements
One of the options on the Developer Services tool is the "Convert SQL Command to Code". That's a very useful tool when we have a SQL statement on the clipboard (most likely copied from SQL Management Studio or some other place like that), and we want to use that statement in .NET code. This tool takes the statement, and formats it in a way to be called through a DbCommand in .NET.
We've just relased a new version of the tool with three main changes:
- Enhancement: The tool used to wrap the SQL statement into concatenated strings, which is not the preferrable way to do it. Now we've added the option to use a StringBuilder instead.
- Change: The tool used to use the SqlCommand type, instantiating the class directly. That's been changed so that the variable is typed to IDbCommand, and the Biz Obj's NewDbCommand factory method is used instead (since this is the way we do things in Milos!).
- New feature: added an option to extract SQL statement from C# code and output it to plain SQL syntax.
How to use it
We usually work a SQL statement in SQL Management Studio to test it and make sure we get it right. Once we feel good about the SQL query, we copy it to the clipboard, go to the SQL to .NET tab on the tool, paste it on the "SQL Command" textbox, and click the Convert button. We then copy the "Resulting .NET Code" into our .NET class.
Eventually, when troubleshooting things, we may want to take the SQL query out of the .NET code and then paste it into SQL Management Studio. Just paste the .NET code where the query is wrapped, paste it onto the ".NET Code" textbox on the ".NET to SQL" of the tool, and hit Convert. The "Resulting SQL Code" textbox will have the plain SQL statement stripped out of the .NET code.
Note there are two other alternatives for troubleshooting problems with SQL queries:
- Put a break point in the source code after the Command object is built, and when execution stops, copy the value out of the command.CommandText property.
- Run SQL Profiler; you'll see the SQL query being executed; you can then copy that from the profiles into Management Studio (the good thing about this one is that it will have the parameters passed to the query as well.
These things are invaluable to gain time when we're already busy enough trying to figure why something isn't working. :)
Posted @ 6:04 PM by Lassala, Claudio (email@example.com)