Represents the base class for generated TypedMapper classes. A TypedMapper provides a type-safe implementation of an IMapper based on its meta-data.

Namespace: NetQuarry.Data
Assembly: EAP.Mapper (in EAP.Mapper.dll) Version: 2.0.0.0 (4.5.2.0)

Syntax

C#
public abstract class TypedMapper : IDisposable
Visual Basic
Public MustInherit Class TypedMapper
	Implements IDisposable

Remarks

Generated TypedMapper-derived classes are useful when manipulating an IMapper and you would like to treat it more like a type-safe object. They are also useful as a base class for higher level business objects that you may require in your extensions. A TypedMapper has a Get and Set property for each IField defined in the mapper. If you have fields with an include flavor you may need to add a Get and Set property in your derived class as, by default, the generator will not pick up these fields. There are a number of meta-data settings that can be used to tune TypedMapper generation for a particular IMapper:

  • SkipCodeGeneration - Prevents code generation for the mapper.
  • CodeGenFlavor - Flavor (from Flavors) to set on the mapper during code generation.
  • CodeGenOptions - Options for affecting code generation at the mapper level.
  • ClassName - The name to use when generating the TypedMapper C# class. Normally used where Key a C# reserved word. By default the Key is used.
  • ForceCodeGen - Force Get/Set generation for the field (even if include is set).
  • PropertyName - The name to use for the property element in the generated TypedMapper for the corresponding IField. Normally used where Key a C# reserved word. By default the Key is used.
  • FieldCodeGenOptions - Options for affecting code generation at the field level.

You typically use a TypedMapper in your extensions. You can create a TypedMapper and attach it to the sender (an IMapper) of the event or you can use the TypedMapper derivative to create a new mapper - either for the purpose of creating a new row or reading/updating an existing one. Connecting a TypedMapper via one of the constructors or Attach<(Of <<'(T>)>>)(IMapper) is very inexpensive and generally a safer way to work with a mapper. You should, however, use good judgement when creating a new instance of a mapper as a query of the operational database is required.

You should call Close()()()() on any TypedMapper instantiated using one of the TypedMapper Open methods (e.g. Open, OpenReader, OpenNew), however, you should generally not call Close()()()() on TypedMappers attached to an existing IMapper using Attach<(Of <<'(T>)>>)(IMapper) or AttachExisting(IMapper). Instantiating a TypedMapper using one of the Open methods instantiates a new IMapper which should be closed when the TypedMapper is no longer of use. Mappers attached to a TypedMapper, on the other hand, generally should survive the TypedMapper (e.g. when attached to a mapper that is firing the current event).

Examples

The following example shows how to use a TypedMapper derivative to get and set values in a RowBeforeUpdate(IMapper, EAPEventArgs) extension. In this case the directly generated code isn't used, rather classes derived from the generated classes. These classes are defined in a namespace different than the generated classes as well. (iLuxCars.Data vs. iLuxCars.Data.Generated).

C# Copy imageCopy
public override void RowBeforeUpdate(IMapper sender, EAPEventArgs e)
{   
    //--- Simple attach to the Offer Comparables TypedMapper derivative

    iLuxCars.Data.OfferComp oc = new iLuxCars.Data.OfferComp(sender);                       

    //--- build a row filter for a single row (the vehicle) and get the description without color
    //--- and create a mapper positioned to this row using the constructor
    //--- Note that you don't have to call close on the mapper if you create the object in a C# 'using'
    //--- construct.

    string rowFilter = string.Format("vehicle_id = '{0}'", oc.vehicle_id);
    using (iLuxCars.Data.Vehicle veh = new iLuxCars.Data.Vehicle(sender.Application, rowFilter))
    {
        string description = veh.NormalizedDescription;     //--- custom property
        oc.UpdateFromComparables(description);
    }

    //--- get important values from the TypedMapper
    //--- each property get is equivalent to the statment commented out to the right

    decimal iluxAvg = oc.ilux_avg_amt; // EAPUtil.ToDecimal(sender.Fields["ilux_avg_amt"].Value, 0);
    decimal mmrAvg = oc.mmr_avg_amt; // EAPUtil.ToDecimal(sender.Fields["mmr_avg_amt"].Value, 0);
    decimal kbbAvg = oc.kbb_amt; // EAPUtil.ToDecimal(sender.Fields["kbb_amt"].Value, 0);
    decimal targetAmt = oc.target_amt; // EAPUtil.ToDecimal(sender.Fields["target_amt"].Value, 0);
}

The following example shows a TypedMapper derived class that handles the RowBeforeInsert(IMapper, EAPEventArgs) event on the mapper.

C# Copy imageCopy
//--- The derived class. 
class VehicleRequest : iLuxCars.Data.Generated.vehicle_request
{
    public VehicleRequest(NetQuarry.Data.IMapper mapperVehicleRequest)
        : base(mapperVehicleRequest)
    {
    }

    public void OnRowBeforeInsert()
    {
        /// --- lookup the current dealer from the user id if it's missing
        IAppContext appCxt = this.Mapper.Application;

        if (string.IsNullOrEmpty(this.dealer_id.ToString()))
        {
            string dealerID = iLuxCars.Common.EmailHelper.GetUserDealerID(appCxt);
            this.dealer_id = new Guid(dealerID);
        }
    }
}

//--- The extension class calling the TypedMapper Business Object.
public class XExt : NetQuarry.Data.MapperExtensionKernel
{
    public XExt() { }

    public override void RowBeforeInsert(IMapper sender, EAPEventArgs e)
    {
        iLuxCars.Data.VehicleRequest vehReq = new iLuxCars.Data.VehicleRequest(sender);
        vehReq.OnRowBeforeInsert();
    }
}

The following example creates a new TypedMapper derivative, sets some values, and saves the record.

C# Copy imageCopy
//--- create a new instance of our subclassed vehicle TypedMapper and attach it to the mapper passed in

Vehicle     typedVehicle = new Vehicle(mapperVehicle);

//--- call the .NormalizedDescription on our subclass

string      normalizedDescription = typedVehicle.NormalizedDescription;

//--- Create a new instance of our subclassed offer_comp (TypedMapper). This calls a 
//--- helper method to create a mapper and move it to a new record, read for setting values.

using (OfferComp oc = OfferComp.OpenNew(appCxt))
{
    //--- Set the offer_id (FK) from the param

    oc.offer_id = new Guid(offerID);

    //--- Set the vehicle_id now (this isn't actually necessary as this is really a field from another 
    //--- table populated from the view.)

    oc.vehicle_id = typedVehicle.vehicle_id;

    //--- call our custom method to update the values from comparables in the db

    oc.UpdateFromComparables(normalizedDescription);

    //--- save

    oc.Save();

    /// --- It is safe to call oc.Close() but not necessary if you
    /// --- are inside a using block.
}

Generating TypedMappers

The C# source code for TypedMappers is generated using the platform's manually-invoked CodeGen facility. The CodeGen program creates a C# class for each IMapper definition. Typically all the generated C# classes are contained in the project's TypedMapeprs.cs file.

To generate typed mappers you run the command line utility EAP.Tools.CodeGen.EXE installed in the <application root>/bin folder. The utility takes the following arguments (the first argument (-AppID) is required):

  1. -AppID:<appid> - the ID for your application.
  2. -CamelCase - (optional) include this to convert property names to a CamelCase representation. By default, for each IField in the mapper the property name is the same as the Key.
  3. -NullableNumerics - (optional) include this to declare the numeric field properties as Nullable (e.g., int fields will be declared as int?). By default, numeric properties are defined as their value types and 0 (or false) is returned if the value is null.
  4. -NoNullStrings - (optional) include this to force string properties to return an empty string instead of null when the field value is null. By default, null values are returned as null strings.
  5. -Docs - (optional) include this to generate more complete in-line comment headers for documentation generation.
You must create a config section in the EAP.Tools.CodeGen.exe.config with the options. Example:
 Copy imageCopy
<configSections>
    <section name="IssueTrak" type="System.Configuration.NameValueSectionHandler" />
</configSections>

<IssueTrak>
    <!-- connection strings -->
    <add key="repository_connect" value="Provider=SQLOLEDB;Data Source=.;Initial Catalog=issues_meta;Integrated Security=SSPI" />    
    <add key="IssueTrak_connect" value="Provider=SQLOLEDB;Data Source=.;Initial Catalog=issues_data;Integrated Security=SSPI" />

    <!-- optional, normally set by the web application context -->
    <add key="RootPath" value="c:\inetpub\wwwroot" />
    <add key="RootURL" value="http://localhost" />

    <!-- full path to the file to be generated -->
    <add key="GeneratedFileName" value="C:\NetQuarry\IssueTrak\Source\Data\Generated\TypedMappers.cs" />
    <!-- namespace to use for the generated TypedMapper classes -->
    <add key="Namespace" value="IssueTrak.Data" />
</IssueTrak>

Example:

 Copy imageCopy
SET APP_KEY=IssueTrak
EAP.Tools.CodeGen -AppID:%APP_KEY% -CamelCase -NoNullStrings

Using the generated classes

You should not write code or otherwise change the generated classes, rather you should dervive a class from a generated class and add application specific logic to the derived class. The following class derives from the generated base and adds a method that is to be called during the RowBeforeInsert event in an extension (in the second block).

 Copy imageCopy
public class Dealer : iLuxCars.Data.Generated.dealer<Dealer>
{
    public Dealer() : base() {}
    public Dealer(NetQuarry.Data.IMapper mapperDealer) : base(mapperDealer) { }       

    public void OnBeforeInsert()
    {
        string rowFilter = base.Fields.dealership_nm.BuildFilter();
        rowFilter += "" AND "" + base.Fields.postal_code.BuildFilter();
        using (Dealership boDealership = Dealership.Open(this.Application, rowFilter))
        {
            if (boDealership.HasRecords)
                this.dealership_id = boDealership.dealership_id;
        }
    }
}

public override void RowBeforeInsert(IMapper sender, EAPEventArgs e)
{            
    iLuxCars.Data.Dealer boDealer = new iLuxCars.Data.Dealer(sender);
    boDealer.OnBeforeInsert();
}

Inheritance Hierarchy

System..::..Object
  NetQuarry.Data..::..TypedMapper

See Also