Milos Solution Platform (External Blog)

The Milos Solution Platform is .NET's premier platform for building business applications. This blog is meant for developers who use or evaluate Milos. This blog is used to share tidbits of information provided by the Milos developers at EPS. Many of the posts put the spotlight on new features. We generally recommend that all Milos users (developers) at least scan this blog to keep up with the Milos news.

Content Area Footer

Saturday, October 13, 2007
'Split-Table' Table Updated

Here is a new feature that only some people will need, but those who need it really do... ;-)

The Milos BusinessObject class features a SaveTable() method, with takes a DataTable as a parameter (among other things) and can then (by means of using various DataService features) simply persist all the changes in the data table back to the database server (whether that's SQL Server or some other database technology). This feature is used extensively by the BusinessEntity infrastructure (among other things). So for instance, when you load a business entity that has a master table and several child tables, each of the tables inside the entity is saved using the SaveTable() method.

However, it has been brought to our attention that people sometimes like to load tables into entities or DataSets that are not just simple tables, but they may be created by joins that incorporate multiple tables. In that case the SaveTable() method was not able to save the table, since every record in the DataTable really mapped to different tables in the database. We have now added a feature to Milos that can handle this scenario in many (although not all!) cases. The basic idea is this: We provide a new SaveTable() overload with parameters that allow you to indicate which fields to include in the save operation, and what the table name maps to, and even field maps in case some of the fields are renamed.

So let's say you created a join that returned a table that has fields from a Contacts table, such as ContactID (maps to ID), FirstName, LastName, and also fields from a 1:1 joined CustomerInformation table like CustomerID (maps to ID), CustomerNumber and CreditLimit. You could save this information back to the database in a two-step operation, like so:

string[] contactFields =
    new string[] { "ContactID", "FirstName", "LastName" };
Dictionary<string, string> contactFieldMaps =
    new Dictionary<string, string>();
fieldMaps.Add("ContactID", "ID");
bool retVal = this.SaveTable(
    existingDataSet.Tables["CustInfo"], "ID",
    "Contacts", contactFields, contactFieldMaps, false);

if (retVal)
    string[] contactFields = new string[]
        { "CustomerID", "CustomerNumber", "CreditLimit" };
    Dictionary<string, string> contactFieldMaps =
        new Dictionary<string, string>();
    fieldMaps.Add("CustomerID", "ID");
    bool retVal = this.SaveTable(
        existingDataSet.Tables["CustInfo"], "ID",
        "CustomerInformation", contactFields,
        contactFieldMaps, true);

In this example, the first SaveTable() operation is limited to the ContactID, FirstName, and LastName fields. Also, the primary key for the Contacts table is really ID, so we create a map for that. (This works for all fields, not just primary keys). If that save is successful, we perform a second save operation for the remaining fields. Not that in the second operation, we pass a true as the last parameter, which flags the data table as unchanged in memory (this is not done after the first save, since other changes still exist).

So this works nicely, but there are a few things you need to know. First, this works best if the table contains 1:1 relationship data. In one-to-many scenarios, the parent "record" exists multiple times, and thus really shouldn't be updated. You can still use the same functionality to update the information from the second part of the table, but you should be very careful updating the parent information, since it will potentially result in multiple updates that can each override each other. Another potential issue is that in memory, each record only has one record state. So the record is either flagged as unchanged, deleted, modified, or added. However, if the parent-part is modified, but the child-part should be considered added, then that would not work and the generated update statements would be incorrect and potentially fail, or - worse - cause incorrect data to be written to the database. So be careful with that.

One aspect of this that isn't immediately obvious is that this new functionality can also be used in scenarios where you just query a single table, but the update needs to map field names, or limit the update to certain fields. For instance, if an empty string array of field names is passed to this method and a mapping dictionary is passed, then all fields will be saved, but they can be mapped. Or, you can pass an empty dictionary, but pass a limiting list of field names, to exclude certain fields from update. Both scenarios can be very useful in a number of scenarios.


Posted @ 11:48 AM by Egger, Markus ( -
Comments (9)

Friday, October 12, 2007
Minor String-Array Helper Method

This is a pretty small item, but I find it useful in a lot of scenarios: There now is a new ArrayContainsString() method on the StringHelper object. It provides a quick way to check whether a certain string array contains a certain string, and it can do so in a case insensitive fashion:

string[] testArray = new string[] { "One", "Two", "Three" };
bool result1 = StringHelper.ArrayContainsString(testArray, "one", true); // returns true
bool result2 = StringHelper.ArrayContainsString(testArray, "one");       // returns false
bool result3 = StringHelper.ArrayContainsString(testArray, "One");       // returns true
bool result4 = StringHelper.ArrayContainsString(testArray, "Four");      // returns false

As I said, this is not an earth-shaking feature, but it is kinda nifty...

Posted @ 2:26 PM by Egger, Markus ( -
Comments (9)








Syndication RSS 2.0 RSS 2.0

All My Blogs:
My personal blogs:
Dev and Publishing Dev and Publishing
Travel and Internat. Living Travel and Internat. Living
Other blogs I contribute to:
Milos Blog (US) Milos Blog (US)
VFPConv. Dev Blog (US) VFPConv. Dev Blog (US)
VFPConv. Dev Blog (DE) VFPConv. Dev Blog (DE)


Blog Archives
All Blog Posts

    November (1)
    July (2)
    February (2)
    January (1)
    December (1)
    October (3)
    June (1)
    April (3)
    February (1)
    January (1)
    December (1)
    October (2)
    September (2)
    July (1)
    June (2)
    May (4)
    April (6)
    March (8)
    February (3)
    January (2)
    December (2)
    November (2)




This Blog is powered by MilosTM Collaboration Components.