AdFactum ObjectMapper .NET Blog

Official blog of the AdFactum ObjectMapper .NET

Attribute: [View]

Posted by Gerhard Stephan on January 18th, 2008

This attribute can be used to define that a class is mapped to a database view.

      [View („VW_CONTACTS“)]

      public class Contact : ValueObject

 

The attribute is important for the Persisters, because some selects will fired in a different way, if you query a database view. If you want to map a database table, you can use the attribute called "Table".

Posted in Attributes | No Comments »

New Release – AdFactum ObjectMapper .NET 2.2.2418.0

Posted by Gerhard Stephan on January 18th, 2008

Four days after the last release I have to publish a small bug fix for all oracle users.

The last change, adding the ROWID to all pageselects, did not work, when querying a database view. And that’s correct, because a database view does not offer a ROWID. So what did I change? It’s now possible to define, that a .NET class is mapped to a database view. This can be done by using the new attribute called "View", instead of using the attribute "Table".

As a second bugfix I changed WithClause. Using the WithClause in prior versions could force a cartesian product, because all tables of the With-Clause have been exposed to the Parent SQL, which is an unwanted behaviour.

Hoping that this will be the last hotfix for this month I wish you a great weekend.

Cheers
– Gerhard

Posted in Releases | No Comments »

New Release – AdFactum ObjectMapper .NET 2.1.2414.0

Posted by Gerhard Stephan on January 14th, 2008

Today I present the first release of the AdFactum ObjectMapper .NET within the new year. So what does it cover? This release is one of the big one and covers a lot of minor changes and one or two bigger issues.

First of all I added a new persister especially for the old Sql Server 2000 version, which does not support the analysis functions used by the paging algorithm. As another big new feature, I added a "DeleteRecursive" method which allows to delete object trees by using a given hierarchy level.

The minor features are less impressive, but important to know:  Many method signatures have changed from using the old collections to the new generic collections. That makes it more easy to use this methods. Furthermore I changed a lot of code fragments so that they are FxCop conform and I reduced duplicated code fragments.

Following bugs have been fixed:

When using the Oracle Paging algorithm there has been a bug when paging a sorted list with identical sort values. Oracle retrieved differend row data. To solve this issue the ROWID has now been added as an additional sorting column.

The SQL Persister for Windows CE is now able to using SelectDistinct (which causes an error in earlier versions). Virtual Links are now correctly quoted, so that reserved words can  be used for it and SelectIds on XmlPersister will now work even if the target object is not defined within the XML file.

So that’s a lot stuff. Hope that everything works for your suffiency. If not, don’t hesitate to write within the forum or answer to this blog entry.

Wish you a great new year.
Cheers

– Gerhard

Posted in Releases | No Comments »

New Release – AdFactum ObjectMapper .NET 2.0.2307.0

Posted by Gerhard Stephan on December 7th, 2007

This version covers one new query condition, with that you can use the Sql  "with clause" sub query replacement.  That feature gives you a powerful optimization feature, if you have many sub selects (SubSelect) within your sql query. In best case, these sub selects can be reduced to one, when using the "with clause" feature.

More information about using the withclause can be found here: http://blog.objectmapper.net/2007/12/07/using-the-sql-99-with-clause/

So, I wish you lot of fun with the new version.
Cheers

– Gerhard

Posted in Releases | No Comments »

How to use the SQL-99 with clause.

Posted by Gerhard Stephan on December 7th, 2007

The SQL-99 with clause is used for substitute where conditions, if you have a sql with multiple sub selects. Puhh. It’s Hard to explain. But: Imagine you have a sql query like the following one:

 

select * from tp_anwender where anwender in

 (select anwender from tp_entries where Computer = ‘xyz’ /* more queries */ and Rechte = 1 union all

  select anwender from tp_entries where Computer = ‘xyz’ /* more queries */ and Rechte = 2 union all

  select anwender from tp_entries where Computer = ‘xyz’ /* more queries */ and Rechte = 3);

 

Sure. It’s not the best example. But you can see, that the where conditions in the sub selects are almost the same. Only the "Rechte" column differs. This can be very good optimized, when using the with clause.

 

with sub01 as (

      select * from tp_entries e where Computer = ‘xyz’ /* more queries */

)

select * from tp_anwender where anwender in

 (select anwender from sub01 where Rechte = 1 union all

  select anwender from sub01 where Rechte = 2 union all

  select anwender from sub01 where Rechte = 3);

 

To build such queries, the AdFactum ObjectMapper .NET does now support the "with clause" for Oracle and the Sql Server. Microsoft Access and SqlServerCE won’t support the with clause.

 

WithClause subClause = new WithClause("sub01", typeof(TpEntries),

    new AndCondition(typeof (TpEntries), "Computer", "xyz"));

 

SubSelect anwender01 = new SubSelect(typeof(TpEntries), "Anwender",

    new AndCondition(typeof(TpEntries), "Rechte", 1),

    new TableReplacement(typeof(TpEntries), "sub01"));

 

SubSelect anwender02 = new SubSelect(typeof(TpEntries), "Anwender",

    new AndCondition(typeof(TpEntries), "Rechte", 2),

    new TableReplacement(typeof(TpEntries), "sub01"));

 

ICondition selection = new ConditionList( subClause,

    new InCondition(typeof(TpAnwender), "Anwender"

    new UnionAll(activityId01, activityId02)));

 

using (AdFactum.Data.ObjectMapper mapper = OBM.CreateMapper(Connection))

{

    int result = mapper.Count(typeof(TpAnwender), selection);

    …

)

 

If you have any questions to this new functionality, don’t hesitate to ask.

That’s all for now folks.

 

Wish you a great weekend.

 

Cheers

– Gerhard

Posted in HowTo | 1 Comment »

Attribute: [ProjectOntoProperty]

Posted by Gerhard Stephan on November 12th, 2007

The attribute [ProjectOntoProperty] is used to build projections of distinct source tables.

Defintion:

  1. A projection is a result subset of the queried tables.
  2. A projection can be used as a query result, instead of quering an IValueObject type.

That implicates, that a projection class (that uses the ProjectOntoProperty) must not implement the IValueObject interface.

Example:

Imagine you would have two value object types: A Company with their employees. Now you wanto to query the employees. As an additional information you want to output the name of the company where the employees are working. Because of this, you would have a a result type that is compound of the type company and employee.

List<FullFeaturedEmployee> names = new List<FullFeaturedEmployee>(

      new ListAdapter<FullFeaturedEmployee>(

            mapper.Select(

                  typeof(FullFeaturedEmployee),

                  new CollectionJoin(

                        typeof(Company),

                        "Employees",

                        typeof(Employee)

                  )

            )));

 

    /// <summary>

    /// Projects results of the company legalname and the employee names

    /// </summary>

    public class FullFeaturedEmployee

    {

        private int companyId;

        private int employeeId;

 

        private string companyName;

        private string firstName;

        private string lastName;

 

        [ProjectOntoProperty(typeof(Company), "LegalName")]

        public string CompanyName

        {

            get { return companyName; }

            set { companyName = value; }

        }

 

        [ProjectOntoProperty(typeof(Employee), "FirstName")]

        public string FirstName

        {

            get { return firstName; }

            set { firstName = value; }

        }

 

        [ProjectOntoProperty(typeof(Employee), "LastName")]

        public string LastName

        {

            get { return lastName; }

            set { lastName = value; }

        }

 

        [ProjectOntoProperty(typeof(Company), "Id")]

        public int CompanyId

        {

            get { return companyId; }

            set { companyId = value; }

        }

 

        [ProjectOntoProperty(typeof(Employee), "Id")]

        public int EmployeeId

        {

            get { return employeeId; }

            set { employeeId = value; }

        }

    }

 

Important:

A projection class (that uses the ProjectOntoProperty) must not implement the IValueObject interface.

Posted in Attributes | No Comments »

Public Holiday Toolkit v1.0

Posted by Gerhard Stephan on November 2nd, 2007

Today the Public Holiday Toolkit v1.0 has been published. The Toolkit enables the developer to show public holidays for several countries within .NET applications. So why do I post it here? Because the Public Holiday Toolkit is based on the AdFactum ObjectMapper .NET. That makes it to a perfect example for how to use the XML Persister. Furthermore the model can be perfectly adapted into your own entity model, in order to store the holiday definitions into a real database, instead of using an XML file.

So have fun with it.

Cheers
– Gerhard

Here’s the URL: Public Holiday Toolkit v1.0

Posted in Miscellaneous | No Comments »

New Release – AdFactum ObjectMapper .NET 2.0.2129.0

Posted by Gerhard Stephan on October 30th, 2007

Today I’m proud to release version 2.0 of the AdFactum ObjectMapper .NET. This major release covers new key features like a first LINQ implementation, new projection classes and several bug fixes regarding the XML persister.

First of all, the ObjectMapper .NET does now understand the basic LINQ syntax. Please keep in mind that this is a first implementation and that it does not cover the complete functionality of LINQ. But it’s a first step. Be sure that the next release of the ObjectMapper .NET will cover a lot more LINQ features than it does today.

Linq Support

var orders = mapper.Query<Order>();

var customers = mapper.Query<Customer>();

 

var mexicanOrders =

from order in orders

join customer in customers on order.Customer equals customer

where customer.Country == "Mexico"

select order;

 

You’ll find several LINQ examples within the NUnit Test Cases.  

Anonymous Types

Because the dotNet Framework 3.0 does now support anonymous types, the AdFactum ObjectMapper .NET had to support these types in order to be LINQ conform.  Have a look at the following LINQ query.

var mexicanOrders =
      from order in orders
      join customer in customers on order.Customer equals customer
      where customer.Country == "Mexico"
           
select new {
                  customer.CompanyName,
                  customer.ContactName,
                  order.OrderDate,
                  order.ShipName };

 

The result of this query is a list with objects of an anonymous type. The anonymous type has four properties (CompanyName, ContactName, OrderDate and ShipName).

Projection class

The support of anonymous types leads to a new feature of the AdFactum ObjectMapper .NET. It was a absolute necessity to add an equal feature to the non LINQ version. That new feature has been called projection classes. A projection class is a class where the properties are used to mirror the results of multiple sources into one projection. 

     /// <summary>
    /// Class used for projections
    /// A class that is used for projects must not be a ValueObject!
    /// </summary>

    public class OrderCustomer
    {
        private string companyName;
        private string contactName;
        private string shipName;

        /// <summary>
        /// Gets or sets the company name.
        /// </summary>
        /// <value>The company name.</value>
        [ProjectOntoProperty(typeof(Customer), "CompanyName")]
        public int CompanyName
        {
            get { return companyName; }
            set { companyName = value;  }
        }

        /// <summary>
        /// Gets or sets the contact name.
        /// </summary>
        /// <value>The contact name.</value>
        [ProjectOntoProperty(typeof(Customer), "ContactName")]
        public string ContactName
        {
            get { return contactName; }
            set { contactName = value; }
        }

        /// <summary>
        /// Gets or sets the ship name.
        /// </summary>
        /// <value>The name of the ship.</value>
        [ProjectOntoProperty(typeof(Order), "ShipName")]
        public string ShipName
        {
            get { return shipName; }
            set { shipName = value; }
        }
    }

EXAMPLE:

List<OrderCustomer> names = new List<OrderCustomer>(
      new ListAdapter<OrderCustomer>(
            mapper.Select(typeof (OrderCustomer),
            new Join(typeof (Order), “Customer”, typeof (Customer))));

 

Support of .NET 2003 closed

Because of all these new features and changes it wasn’t possible to keep the .NET 2003 support for the AdFactum ObjectMapper .NET. I hope that not many users are still working with .NET 2003, but there had not been an other solution. Due to this change, it’s necessary to de-install the ObjectMapper .NET first, before installing the new version. 

XML Persister

The Xml Persister has been greatly reworked. It’s now again possible to store object trees into an XML File. I say "again", because this features has been broken in one of the last versions of the AdFactum ObjectMapper .NET.  

Minor Bug Fixes

Last but not least, there have been many minor bug fixes.

  1. There were failures when defining primary keys other than already defined in the base classes, like ValueObject or AutoIncValueObject.
  2. The Access Persister did not throw the correct error number the time a failure occured. This forced the AccessPersister to execute the SQL multiple times before throwing an exception.
  3. Furthermore I implemented a new caching strategy which reduced the amount of cache access significantly.

And a lot of more minor bug fixes / changes that are not counted.

Hope you enjoy the new version.

Cheers
– Gerhard 

kick it on DotNetKicks.com

Posted in Releases | No Comments »

Hierarchy Level Explained

Posted by Gerhard Stephan on October 1st, 2007

The AdFactum ObjectMapper .NET uses hierarchy levels to define the degree of dependence that will be considered when loading or saving.

When loading with hierarchy level 0, the object will be loaded into memory without any dependencies. The same happens when the AdFactum ObjectMapper.NET is storing the objects to database. That means HierarchyLevel.FlatObject, loading and storing without any object dependencies.

For load operations the hierachy level step is always 2.

        public const int FlatObject = 0;

        public const int Dependend1stLvl = 2;

        public const int Dependend2ndLvl = 4;

        public const int AllDependencies = int.MaxValue;

 

In the following example you can see the object dependencies when loading the customer object.

 

For example, when loading the customer with HierarchyLevel.Dependent1stLvl the aggregated Order Objects will be loaded too. When loading the customer with HierarchyLevel.Dependent2ndLvl the OrderItems of the Order Object will be also loaded.

When storing objects to database the Hierarchy Level is even more senstive. That means that you can also specify, whether an object should only update the links to an aggregated object or whether the object should also update the aggregated object too.

These are the intermediate steps 1, 3, 5 and so on. That is, if you only add an existing OrderItem to the Order object, you can store the Order Object with the HierarchyLevel.FlatObjectWithLinks, which updates the link to the OrderItem, but not the OrderItem itself. The difference is very important to know.

For load operations the hierachy level step is always 1.

        public const int FlatObject               = 0;

        public const int FlatObjectWithLinks      = 1;

        public const int Dependend1stLvl          = 2;

        public const int Dependend1stLvlWithLinks = 3;

        public const int Dependend2ndLvl          = 4;

        public const int Dependend2ndLvlWithLinks = 5;

        public const int AllDependencies          = int.MaxValue;

 

In the following example you can see the object dependencies when storing the customer object.

 

For a better understanding I recommend you to output the SQL trace and try to store the object with a different hierarchy levels. That gives you a feeling for, which hierarchy level you use best to get the optimal performance.

 

Posted in Hint | No Comments »

How to check if a property has been changed since last loading the object.

Posted by Gerhard Stephan on September 20th, 2007

Sometimes it’s important for the business logic to know if the UI changed a special property since last loading the object. Maybe this is important for the workflow or other things. Using the AdFactum ObjectMapper .NET you can use a speical pattern for that.

Have a look at the following example. The entity Company has a state called CompanyState. We now want to know, whether that property has been changed by the UI since last loading the object. Therefore we need a second property that holds the orginal value. This property is filled the first time wehn the object is loaded by the AdFactum ObjectMapper .NET. A property with the Ignore attribute checks those two properties to indicate whether the property has been changed or not. It’s important to define the orginal value as a nullable type, because we only want to fill that property the first time when the setter is called.

    public enum CompanyState

    {

        Active,

        Retired,

        Deleted

    }

 

    public class Company

    {

        private CompanyState companyState;

        private CompanyState? orgCompanyState = null;

 

        /// <summary>

        /// Gets or sets the state of the company.

        /// </summary>

        /// <value>The state of the company.</value>

        public CompanyState CompanyState

        {

            get { return companyState;  }

            set {

                companyState = value;

                if (orgCompanyState == null)

                    orgCompanyState = value;

            }

        }

 

        /// <summary>

        /// Gets a value indicating whether the company state changed or not.

        /// </summary>

        /// <value><c>true</c> if company state changed; otherwise, <c>false</c>.</value>

        [Ignore]

        public bool CompanyStateChanged

        {

            get { return companyState != orgCompanyState;  }

        }

    }

 

In our business logic we can now check the CompanyStateChanged property and react on new values within the company state. E.g. send emails or do something else.

That’s all for now.
Cheers

– Gerhard

Posted in HowTo | No Comments »