Archive

Posts Tagged ‘CodeFluent Entities’

Fetch performance of CodeFluent Entities compared to others

March 27, 2014 Leave a comment

CodeFluent Entities has a great way to extend or modify generated code. This can be done through Custom Producers, Sub-Producers or Aspects. In fact, it can happen that you will meet very special requirements during your project, the kind of requirements that will involve some customizations to all of your code. Of course you don’t want to do this job manually by modifying each property or method in your project. Instead you can change the generated code to fit your expectations by using aspect. For a first introduction to aspect development in CodeFluent Entities please visit our blog.

In our situation, after reading Frans Bouma’s blog on benchmark of several ORMs of the .Net platform (Entity Framework, NHibernate, LLBLGen Pro, Linq To Sql and more), we wanted to integrate CodeFluent Entities to the benchmarks he made.

Integrating CodeFluent Entities to the benchmark project

First we downloaded the project from its GitHub repository.

After opening the RawBencher solution we created a CodeFluent Entities Model project:

CodeFluent Entities Project

Also we created a class library project to hold the code generated by CodeFluent Entities:

Class Library Project

Then we added one Business Object Model Producer and one SQL Server Producer to this project:

Solution Explorer

Here is the configuration for each producer:

Business Object Model

Business Object Model

Microsoft SQL Server

Microsoft SQL Server

Then we imported the AdventureWorks database to our CodeFluent Entities model:

Import

Then select the Microsoft SQL Server importer:

SQL Server Importer

Finally, set the connection string as pictured below:

SQL Server importer configuration

Once the import from database was done we built the model project to generate C# code and database stored procedures. After this, for the final step we added a bencher class to call CodeFluent Entities generated code. We basically reproduced the same schema as the existing ones for other ORMs already set up in this benchmarking project.

We are now ready to start the benchmarking!

Running the benchmark and analyzing results

We ran the project in release mode and we got the following results:

Non-change tracking fetches, set fetches (10 runs), no caching:

  1. Handcoded materializer using DbDataReader: 214,63ms
  2. PetaPoco Fast v4.0.3: 285,50ms
  3. Dapper: 306,25ms
  4. Linq to SQL v4: 318,50ms
  5. PetaPoco v4.0.3: 355,00ms
  6. Entity Framework v6: 362,13ms
  7. CodeFluent Entities 551,00ms
  8. ServiceStack OrmList v4.0.9.0: 555,75ms
  9. LLBLGen Pro v4.1.0.0, typed view: 585,00ms
  10. Oak.DynamicDb using dynamic Dto class: 902,50ms

Non-change tracking individual fetches (100 elements, 10 runs), no caching:

  1. CodeFluent Entities: 0,18ms
  2. DataTable, using DbDataAdapter: 0,37ms
  3. Oak.DynamicDb using dynamic Dto class: 0,40ms
  4. LLBLGen Pro v4.1.0.0: 0,44ms
  5. Telerik DataAccess/OpenAccess Fluent v4.0.3: 0,50ms
  6. Telerik DataAccess/OpenAccess Domain v4.0.3: 0,50ms
  7. NHibernate v3.3.1.4000: 0,68ms
  8. Entity Framework v6: 1,85ms
  9. Linq to Sql v4: 2,89ms

We focused only on non-change Tracking mode because it is the one that matches CodeFluent Entities features.

We can see that CodeFluent Entities is ranked at the first place for single fetch operations. Also we can see that it is ranked 7th for the multiple fetch operations.

Of course each ORM offers different features and because of that some of them can have a more naïve approach than others which will check data type conversion for instance or check cache during the fetch. This will lead to a speed difference in execution time.

For example if you compare a SQL hand coded query against any ORM among the ones available in .NET, hand coded query will be for sure faster. In our case we can explain why CodeFluent Entities generated code is taking more time in the multiple set fetch operation. Basically the code generated is doing some additional operations that we can get rid of in this particular scenario:

For instance in this LoadAll method we do not need to check if an element is already contained in the inner list so we should remove the check:

LoadAll

Another example is the ReadReacord method, in this case we do not need to test if the reader is null or not, neither the options and since the type are secure and primitive types we do not need to use the CodeFluent Persistence GetReader methods a simple reader.GetIn32 or reader.GetDate can be used depending on the type:

ReadRecord

After making these changes we can run the benchmark again to see what changed!

Running the benchmark with the adapted code

Here are the new result after code adaptation:

Non-change tracking fetches, set fetches (10 runs), no caching:

  1. Handcoded materializer using DbDataReader: 214,63ms
  2. CodeFluent Entities 273,25ms
  3. PetaPoco Fast v4.0.3: 285,50ms
  4. Dapper: 306,25ms
  5. Linq to SQL v4: 318,50ms
  6. PetaPoco v4.0.3: 355,00ms
  7. Entity Framework v6: 362,13ms
  8. ServiceStack OrmList v4.0.9.0: 555,75ms
  9. LLBLGen Pro v4.1.0.0, typed view: 585,00ms
  10. Oak.DynamicDb using dynamic Dto class: 902,50ms

After these changes CodeFluent Entities is now ranked at the 2nd place just after the hand coded query!

I will now show you how to make these custom changes more generic to apply them to the entire project for instance.

Understanding CodeFluent Entities Aspects

In CodeFluent Entities, the code generation process is model-first and continuous: from your declarative model, a meta-model will be inferred which code generators will then translate into code.

AspectAspects introduce a new notion allowing you to plug into this process. Using aspects you’ll be able to work on this in-memory representation of the model, before anything is produced and dynamically add/remove/modify elements in your model: this is what we call dynamic modeling. In a nutshell, in CodeFluent Entities, dynamic modeling is materialized as aspects and it allows developers to inject extra-behaviors in models.

You can easily see what the inferred model contains by selecting the option “View Inferred Model” on your project:

View Inferred Model

Then you can get details about any method or property of your code, for instance in our case the LoadAll method of the SalesOrderHeader entity:

Inferred Model

This inferred model will be used by the Business Object Model Producer we configured before to generate our code.

When you build your project, the enabled producers are instantiated to work on your model. With CodeFluent Entities you can interact at moment of the code production. For example you can change on the fly the behavior of your CodeDom producer (aka Business Object Model Producer) by accessing its instance:

CodeDomProducer codeDomProducer = Project.Producers.GetProducerInstance<CodeDomProducer>();

codeDomProducer.CodeDomProduction += (sender, e) =>
{
    //write your code here ...
}

And then you can manipulate this codeDomProducer object to change the body of your methods or do any other change to the generated code. In our case this will be very helpful to change the body of the LoadAll and ReadRecord methods.

Making code adaptation using aspects

In fact the changes we made can be reproduced automatically among the code by using a custom aspect that will interact with the Business Object Model Producer on the fly.

You can download the FastReader.xml file that contains the aspect we developed to make our customizations generic.

To remind you here is what the LoadAll method looked like before using the aspect:

LoadAll Before

Here is the new version of the same function:

LoadAll After

Another example is the ReadRecord method; here is what it was like before using the aspect:

Read Record Before

After enabling the aspect the method is replaced by a new one with the name FastReadRecord:

Read Record After

CodeFluent Entities offers many ways to customize the code generation and aspects is only one way among the others. In fact code customization can also be done by using sub-producers or patch-producers. Each technic has its pros and cons and in our case aspects was the best way to reach our goal. If you want to read more about sub-producers or patch producers please visit our blog here and here.

I hope this article helped you to figure out the flexibility of CodeFluent Entities.

Feel free to download and use the FastReader.xml aspect if you need.
Moreover, the full source code is available on our GitHub Profile.

Happy Adapting!

The R&D team.

Define your own CodeFluent Entities Keyboard shortcuts

March 24, 2014 1 comment

Some of you ask us if we can create your own keyboard shortcuts with CodeFluent Entities. Yes, of course. You can assign a shortcut to add an entity or a property into your CodeFluent Entities surface thanks to Visual Studio Keyboard Commands. While we do not set default keyboard shortcuts, you can define your own:

  • Open the Visual Studio Options dialog (Tools / Options / Environment / Keyboard)
  • Select the desired command (search command containing CodeFluent)
  • Define the keyboard shortcut

shortcut

Below is a list of the most common CodeFluent commands:

  • Add Entity: OtherContextMenus.CodeFluentSurface.Add.Entity
  • Add Property: OtherContextMenus.CodeFluentSurface.Add.Property
  • Add Rule: OtherContextMenus.CodeFluentSurface.Add.Rule
  • Add Instance: OtherContextMenus.CodeFluentSurface.Add.Instance
  • Model Search: OtherContextMenus.CodeFluentSurface.ModelSearch (my favorite!)
  • Arrange Surface: OtherContextMenus.CodeFluentSurface.Arrange.Surface

Happy shortcutting, The R&D Team

Multi-database deployment with PowerShell and the Pivot Script Runner – Part 2

March 6, 2014 Leave a comment

In Part 1 of this article, we looked at using the PowerShell strengths to automate the process of updating several databases through the PivotRunner tool.

Now, we want to go further and create a PowerShell command, better known as a Cmdlet.

Build the Cmdlet

A Cmdlet can be built directly in a Powershell script, or through the .NET Framework. We need to inherit from System.Management.Automation.Cmdlet and define its naming attributes therefor.

By agreement, the name of a Cmdlet consists of a verb, followed by a dash and a name (e.g: Get-ChildItem andAdd-PSSnapIn):

using System.Management.Automation;

namespace CodeFluentEntitiesCmdlet
{
    [Cmdlet(VerbsData.Update, "CFEDatabase", SupportsShouldProcess = true, 
            ConfirmImpact = ConfirmImpact.High)]
    public class UpdateCFEDatabase : Cmdlet
    {
    }
}

Here, the Cmdlet’s name will be Update-CFEDatabase.

Use the following PowerShell command: Copy ([PSObject].Assembly.Location) C:\MyDllPath to find the System.Management.Automation library

SupportsShouldProcess and ConfirmImpact attributes allow the Cmdlet to use the PowerShell Requesting Confirmation feature.

The Cmdlet abstract class includes a fairly advanced command parameters engine to define and manage parameters:

[Parameter(Mandatory = true)]
public string ConnectionString { get; set; }

[Parameter(Mandatory = true)]
public string PivotFilePath { get; set; }

The Mandatory term is used to warn the command parameters engine of whether or not a parameter is required.

Cmdlet also exposes some methods which can be overriden. These pipeline methods allow the cmdlet to perform pre-processing operations, input processing operations, and post-processing operations.

Here, we’ll just override the ProcessRecord method:

protected override void ProcessRecord()
{
  // Process logic code
}

Then, we need to use the PivotRunner which is located in the CodeFluent.Runtime.Database assembly.

The tool takes the connection string and the pivot script producer output file as parameters:

using CodeFluent.Runtime;
using CodeFluent.Runtime.Database.Management.SqlServer;

private void UpdateDatabase()
{
    try
    {
        PivotRunner runner = new PivotRunner(PivotFilePath);

        runner.ConnectionString = ConnectionString;

        if (!runner.Database.Exists)
        {
            WriteObject("Error: The ConnectionString parameter does not lead to an existing database!");
            return;
        }
        runner.Run();
    }
    catch (Exception e)
    {
        WriteObject("An exception has been thrown during the update process: " + e.Message);
    }
}

Do not forget to reference CodeFluent.Runtime.dll and CodeFluent.Runtime.Database.dll!

Moreover, we can recover the PivotRunner output (internal logs) by providing an IServiceHost implementation:

public class CmdletLogger : IServiceHost
{
    private Cmdlet _cmdLet;

    public CmdletLogger(Cmdlet cmdlet)
    { 
        _cmdLet = cmdlet;
    }

    public void Log(object value)
    {
        _cmdLet.WriteObject(value);
    }
}

runner.Logger = new CmdletLogger(this);
runner.Run();

Powershell integration

The Cmdlet is now finished! :)

Now we’ll see how to call it from Powershell! Here, we have several options, but we shall see the PSSnapIn one.

The “Writing a Windows PowerShell Snap-in” article shows that a PSSnapIn is mostly a descriptive object which inherits from System.Configuration.Install.Installer and is used to register all the cmdlets and providers in an assembly.

So, let’s implement our Powershell snap-in:

using System.ComponentModel;
using System.Management.Automation;

namespace CodeFluentEntitiesCmdlet
{
    [RunInstaller(true)]
    public class CodeFluentEntitiesCmdletSnapin01 : PSSnapIn
    {
        public CodeFluentEntitiesCmdletSnapin01()
            : base() { }

        public override string Name
        {
            get { return ((object)this).GetType().Name; }
        }

        public override string Vendor
        {
            get { return "SoftFluent"; }
        }

        public override string VendorResource
        {
            get { return string.Format("{0},{1}", Name, Vendor); }
        }

        public override string Description
        {
            get { return "This is a PowerShell snap-in that includes the Update-CFEDatabase cmdlet."; }
        }

        public override string DescriptionResource
        {
            get { return string.Format("{0},{1}", Name, Description); }
        }
    }
}

Then, we build our solution which contains our Cmdlet and the PSSnapIn and finally register the built library thinks to the InstallUtil.exe (located in the installation folder of the .NET Framework):

Administrator rights are required.

Administrator rights are required.

By using the “Get-PSSnapIn –Registered” Powershell command, we can observe that our PSSnapIn is well registered. This component can now be used into your Powershell environment:

Get-PSSnapIn–Registered

The “Add-PSSnapIn” command enables us to use our Cmdlet into the current session of Powershell.

As result, we can update our previously built Powershell script:

param([string[]]$Hosts, [string]$PivotFilePath, [switch]$Confirm = $true)

Add-PSSnapin CodeFluentEntitiesCmdletSnapin01

if ($Hosts -eq $null -or [string]::IsNullOrWhiteSpace($PivotFilePath))
{
    Write-Error "Syntax: .\UpdateDatabase.ps1 -Hosts Host1[, Host2, ...] -PivotFilePath PivotFilePath"
    break
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null

Write-Host "-========- Script started -========-"

$Hosts | foreach {
    $srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') $_

    $online_databases = $srv.Databases | where { $_.Status -eq 1 -and $_.Name.StartsWith("PivotTest_") }
    
    if ($online_databases.Count -eq 0)
    {
        Write-Error "No database found"
        break
    }

    Write-Host "Database list:"
    $online_databases | foreach { Write-Host $_.Name }

    [string]$baseConnectionString = "$($srv.ConnectionContext.ConnectionString);database="
    $online_databases | foreach {
        Update-CFDatabase -ConnectionString "$($baseConnectionString)$($_.Name)" -PivotFilePath $PivotFilePath -Confirm:$Confirm
    }
}

Write-Host "-========-  Script ended  -========-"

We can now simply deploy all changes we’ve recently made on our databases thanks to the Cmdlet and PivotRunner components.

The source code is available for download.

Happy PowerShelling !

The R&D team

Using Microsoft Office as a Front-end

March 4, 2014 1 comment

Using CodeFluent Entities you can generate synchronizable lists which lets you use Microsoft Office Excel (2003 and above) and Microsoft Office Access (2007 and above) as front-end clients of your application. This feature was actually already discussed in this post: Introduction to SharePoint Lists, but we’ll digg a bit further today :).

As a reminder the global architecture is illustrated in the following figure:

Office lists

Before creating the solution, let’s see what the user interface will look like:

Excel

Let’s create the solution

We’ll create 4 projects:

  • A CodeFluent Entities Model project
  • A Class Library project to store the Business Object Model
  • A Database project for the data
  • An empty WebForm project to host the web site and some special web services

Projects

We can add some entities to the model:

Model

Note : there should be only one key (not a composite one) of type Int (or aliases like integer, int32, etc.), with identity (automatic numbering) for the entity to support two-ways synchronization with Office apps, so don’t use Guid or anything else.

Now, let’s also add two computed properties: FullName and Age, and let’s configure the following producers:

  • The SQL Server Producer
  • The Business Object Model (C#) Producer
  • The Office Producer: “Physical Root Path” and “Target directory” must be set to the web project

Now we can build the model. After that, the last thing to do for the synchronization magic to happen is to add a special component that emulates a SharePoint website to our ASP.NET generated web site. We used to provide an ISAPI filter for this, but starting with II7, we now provide a .NET HttpModule class that does the job. So you just need to add the following piece of configuration in the web.config file for this to work:

<system.webServer>
	<modules runAllManagedModulesForAllRequests="true">
		<add name="WssEmulator" type="CodeFluent.Runtime.Web.WssEmulator" />
	</modules>
	<validation validateIntegratedModeConfiguration="false" />
</system.webServer>

Working with Microsoft Access

Open Access and create a new blank database. Select SharePoint List from the External Data tab:

Access

Enter the root URL of your CodeFluent Entities generated “Office” website. Access will then show a list of available lists. Now, choose the list(s) you want to link to.

Access SharePoint

Now you can open and edit your data directly from Access:

Access Sync

Or maybe you would prefer to fill data in an automatically generated form?

Access Forms

Now let’s to do the same thing with Microsoft Excel! :)

Working with Microsoft Excel

To open a list in Excel you need an .IQY file. This “internet query” file format us used by Microsoft Excel to run queries over HTTP(S). CodeFluent Entities generates a web page that contains all available lists and allows Excel to download the associated .IQY file. Launch the web project and navigate to http://localhost/en-us/lists.aspx:
Lists Web

Note that you can also generate .IQY files by using the template located in the “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler\Templates\OfficeServiceHost\ClientIqy” directory, created by the CodeFluent Entities installation.

Select one of them to open your list in Microsoft Excel:

Excel Sync

If you are using Excel 2007 or above you want to read this article: Restoring Two-Way Synchronization on SharePoint Lists Using Excel.

Points of interest

  • Enumerations and relations are selectable through a drop-down list (relations show the property defined as the display property of the related entity)
  • By default, relations (drop-down lists in Excel) load all values from the related entity. You can change that by setting the loadMethodName attribute cfpo:loadMethodName=”LoadMethodCustom”
  • Supports data validation. Excel or Access ensures that values are valid for a given type. For example you can’t write a string into an integer defined column.
  • Supports CodeFluent Entities blob-type columns. They will be displayed as hyperlink in Excel. Click on one of them to download the related file/blob.
  • Supports rich text as HTML. For example if you set a cell value to test (bold), the column cell will contain <strong>Test</strong>
  • Supports Read-only columns (by setting the property Is Read Only to true in the model)
  • Supports HTTP and HTTPS
  • Supports authentication (NTLM, Kerberos, basic authentication with an extra CodeFluent Entities provided module)
  • Supports offline work. Excel can save the data even if the network is unavailable.
  • Create different views of the same Entity, for example one for editing data and another one for viewing data. In the first one you can set FirstName, LastName and Date of birth. In the second one, you may prefer showing the full name and the age (you could use computed properties in this case).
  • Add parameters to your lists
LOAD(string name) 
WHERE FirstName STARTSWITH @name OR LastName STARTSWITH @name

An Excel standard dialog box will prompt you for defined parameters when you open the list from Excel. This is a nice way to filter the list. Note in this mode the list is not updatable, just read-only.

Parameter Value

CodeFluent Entities provides out-of-the box a user friendly way to view and edit data.
Don’t forget that in Microsoft Office Excel 2007, 2010 & 2013, the ability to update the data in SharePoint lists directly from Excel is somehow deprecated. Nevertheless, you should look at SharePoint List Synchronizer to address this issue and restore this two-way sync functionality.

Happy synchronizing!

The R&D team.

The sample source code is available for download.

And the winner is…

February 27, 2014 Leave a comment

In a previous post, we talked about the The CodeFluent Entities Quiz and we asked three questions about basic features.

More than 60% of particpants answered 3 questions correctly. It wasn’t that difficult. :)

Quiz CodeFluent Entities

Here are the answers:

Question 1 : What are the databases supported by CodeFluent Entities?

  • Microsoft SQL Server
  • Microsoft SQL Azure
  • Oracle
  • MySQL
  • PostgreSQL
  • All those mentionned

Question 2 : How can we create Web service with CodeFluent Entities?

  • Creating a T4 template
  • Adding a producer
  • Handwriting

Question 3 : What is the continuous generation?

  • Apply model changes consistently to all layers without losing changes nor data
  • Generate the model in background each time the model is edited
  • The generation process never stop and use 100% of the CPU

Additional Information and References :

PostgreSQL Producer
MySQL Producer
Oracle Database Producer
Microsoft SQL Azure Producer
Microsoft SQL Server Producer
Documentation – Generating
Service Object Model Producer
Generating JSON Web Services from an Existing Database with CodeFluent Entities (Code Project)
Continuous generation (video)

The final draw took place on Febrary 26th, 2014 and the prize was awarded to Guillaume Spera.

Congratulations!

ASP.NET Identity and CodeFluent Entities

February 20, 2014 Leave a comment

The ASP.NET Identity system is designed to replace the previous ASP.NET Membership and Simple Membership systems. It includes profile support, OAuth integration, works with OWIN and is included with the ASP.NET templates shipped with Visual Studio 2013.

ASP.NET Role and Membership providers are out of the box features provided by CodeFluent Entities. Today we’ll see how to create an ASP.NET Identity implementation with CodeFluent Entities.

Let’s do this ! :)

What do we have to do?

ASP.NET Identity provides a bunch of interfaces to define Users, Profiles, Logins, Roles, and how to store them.

A user is defined by the Microsoft.AspNet.Identity.IUser interface and a role is defined by the Microsoft.AspNet.Identity.IRole interface. Those interface are very generics:

public interface IUser
{
    string Id { get; }
    string UserName { get; set; }
}

public interface IRole
{
    string Id { get; }
    string Name { get; set; }
}

ASP.NET Identity also introduce the concept of user store to persist user information. There are different levels of functionalities depending of your needs:

Finally, the Microsoft.AspNet.Identity.UserManager is a higher level API that will coordinate different components such as the UserStore, the Password hasher and the user and password validation in order to manage users in your application.

Now you should have understood that to do our custom ASP.NET Identity we’ll implement the IUser, IRole and IUser*Store interfaces (yes all of them).

Let’s create the model


CodeFluentEntitiesAspNetIdentity

User must implement the IUser interface. This can be done by adding an implementation Rule. The same apply for Role with the IRole interface.

To ensure the uniqueness of the username and role name we declared them at CollectionKey. This will also add automatically the methods User.LoadByUserName and Role.LoadByName.

To implement the UserStore we’ll need two more methods. The first one is to find a customer by a provider key. To do so we add a CFQL method on the user entity:

LOADONE(string providerKey) WHERE ExternalLogins.ProviderKey = @providerKey

We also need to delete a claim by User, Type and Value. This can also be done by CFQL

DELETE(User, Type, Value) WHERE User = @User AND Type = @Type AND Value = @Value

Those methods will be translated into stored procedures during the build process. Note that with CFQL you don’t have to bother with JOIN nor types ! :)

Below is a part of UserStore and RoleStore implementation :

public class UserStore :
    IUserStore<User>,
    IUserPasswordStore<User>,
    IUserSecurityStampStore<User>,
    IUserRoleStore<User>,
    IUserLoginStore<User>,
    IUserClaimStore<User>
{

    public Task CreateAsync(User user)
    {
        if (user == null) throw new ArgumentNullException("user");
        return Task.Run(() => user.Save());
    }

    public Task DeleteAsync(User user)
    {
        if (user == null) throw new ArgumentNullException("user");
        return Task.Run(() => user.Delete());
    }

    public Task<User> FindByIdAsync(string userId)
    {
        return Task.Run(() => User.LoadByEntityKey(userId));
    }
// ...
}

public class RoleStore : IRoleStore<Role>
{
    public Task CreateAsync(Role role)
    {
        return Task.Run(() => role.Save());
    }

    public Task<Role> FindByNameAsync(string roleName)
    {
        return Task.Run(() => Role.LoadByName(roleName));
    }
// ... 
}

Now we can use the UserStore through the UserManager and the RoleStore through the RoleManager:

new UserManager<User>(new UserStore())
new RoleManager<Role>(new RoleStore())

In the article we show that the code generated by CodeFluent Entities can easily be used with really new Framework like ASP.NET Identity. This is possible as CodeFluent Entities generates rock-solid foundation on which you can build your application !

The full implementation is available for download.

Happy user storing,

The R&D team.

Exploring the CodeFluent Runtime: Web Controls – Part 2

February 5, 2014 1 comment

In Part 1 of this series, we looked at some useful controls from the CodeFluent.Runtime.Web assembly.
On the same subject, we’ll explore in this post some other very useful controls for ASP.NET WebForms application.

The first controls are DataSource controls; They aren’t visual but very convenient as they can be bound to any DataBound controls like GridView, ListView, etc.

CountryDataSource (CodeFluent.Runtime.Web.UI.CountryDataSource) gives you a list of countries with a lot of properties, including localization information (EnglishName, NativeName, Location, Region, etc.). The type of the enumerated item is CodeFluent.Runtime.Utilities.Country. You can learn more about this type in the related article on our blog.

<cfe:CountryDataSource ID="CountryDataSource1" runat="server"/>
<asp:GridView ID="GridView2" runat="server" DataSourceID="CountryDataSource1" AllowPaging="true">

CountryDataSource

CultureDataSource (CodeFluent.Runtime.Web.UI.CultureDataSource) gives you a list of CultureInfo (System.Globalization.CultureInfo) and can be bound with any DataBoundControl (GridView, DropDownList…).

<cfe:CultureDataSource ID="CultureDataSource1" runat="server" />
<asp:GridView ID="GridView3" runat="server" DataSourceID="CultureDataSource1" AllowPaging="true">

CultureDataSource

CodeFluent Entities comes with another cool Web Control: the CultureDropDownList.

CultureDropDownList (CodeFluent.Runtime.Web.UI.WebControls.CultureDropDownList) displays automatically for you a DropDownList filled with cultures. With a single line of code, you can let the user change the UI Culture of your website.
First, add this control to your page:

<cfe:CultureDropDownList id="cultures" runat="server" CultureCookieName="culture" AutoPostBack="true" TitleMemberName="EnglishIEStyle" TextMemberName="NativeName" CultureList="en-us;fr-fr" />

The CultureList property lets you set the cultures you want to display. By default, all available cultures (on the current computer) are loaded.

Then, just add the following code in the Global.asax file.

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    CultureDropDownList.SetRequestCulture(Request, "culture"); 
}

The second parameter corresponds to the name of the cookie set in the CultureDropDownList in the page.

Because the CultureDropDownList control is set to AutoPostBack=”true”, when the user selects another culture, the website page will automatically reload with the selected culture. Of course, you need to put in place the ASP.NET globalization mechanism and provide the corresponding resources files :).

FreeForm Control
Now, another topic. Let’s imagine you have several forms to implement as pages on your site, most of them used to get simple input from your users. Let’s suppose you want to send email with the content of the forms. This can be useful for polls for example.

For this, you can use the FreeForm control (CodeFluent.Runtime.Web.UI.WebControls.FreeForm). It allows you to create an arbitrary form, add all the child controls you want to it and then add a piece of code to gather all the user input data. Here is a quick example.

We start with a simple markup:

<cfe:FreeForm ID="FF" runat="server" OnFormChanged="OnFormChanged" DecamelizeOptions="Default" >
    <ItemTemplate>
        <asp:Panel ID="Panel3" runat="server" GroupingText="Personnal Information">
            <asp:Label ID="Label1" runat="server" Text="Preferred Name:" /><br />
            <asp:TextBox ID="TextBox1" runat="server" Text='<%#Bind("PreferredName") %>' /><br />
            <asp:Label ID="Label2" runat="server" Text="City:" /><br />
            <asp:TextBox ID="TextBox3" runat="server" Text='<%#Bind("City") %>' /><br />
        </asp:Panel>
        <asp:Panel ID="Panel4" runat="server" GroupingText="Business Information">
            <asp:Label ID="Label3" runat="server" Text="Your Company:" /><br />
            <asp:TextBox ID="TextBox4" runat="server" Text='<%#Bind("YourCompany") %>' /><br />
            <asp:Label ID="Label4" runat="server" Text="Describe your primary role and function:" /><br />
            <asp:TextBox ID="TextBox5" runat="server" Text='<%#Bind("DescribeYourPrimaryRole_x0026_Function") %>' /><br />
        </asp:Panel>
        <br />
        <asp:Button ID="Button2" runat="server" Text="OK" />
    </ItemTemplate>
</cfe:FreeForm>

We have a form with 4 textboxes and their corresponding labels into 2 panels, plus a standard button to submit :

When the user submits the button, the whole input data will be transformed into a dictionary instance automatically. Each control will provide a dictionary entry in that instance. Notice that all the Text attributes of the textboxes have a standard ASP.NET bind token attached. That token will become the entry field key, and the entry value will be the data entered by the user (whatever the type of this data and the type of the control). To get this dictionary you just need to attach to the FormChanged event and read the Values property of the FormChangedEventArgs parameter, like this:

<script runat="server">
    protected void OnFormChanged(object sender, FormChangedEventArgs e)
    {
        StringBuilder sb = new StringBuilder();

        foreach (DictionaryEntry de in e.Values)
        {
            sb.AppendLine(de.Key + "=" + de.Value + "<br/>");
        }
        
        // NOTE: instead, send email here with the content of the StringBuilder
        litResult.Text = sb.ToString();
    }
</script>     

You may have noticed that we have defined the field names using camel-case and also some weird hexadecimal notation. The FreeForm control has the ability to “decamelize” these keys and unescape the Unicode characters represented by their hexadecimal values. This trick allows us to use anything for key names (although the Bind syntax is much more restrictive). You can define several options in the DecamelizeOption attribute (None, ForceFirstUpper, ForceRestLower, UnescapeUnicode, UnescapeHexadecimal, ReplaceSpacesByUnderscore, ReplaceSpacesByMinus, ReplaceSpacesByDot, KeepFirstUnderscores, DontDecamelizeNumbers, KeepFormattingIndices).

So, this simple example gives you the following result:

Of course, you will hopefully implement something more useful in your project :) You can also imagine having a form generator for power-users, letting them design simple forms and process the Key/Value Dictionary generated by the FreeForm control in a pretty much automatic way.

NumericTextBox Control
Do you need a numeric-only textbox input?. CodeFluent.Runtime.Web has a solution for you: the NumericTextBox control.

The NumericTextBox control (CodeFluent.Runtime.Web.UI.WebControls.NumericTextBox) prevents user from entering non-numeric characters. You can define the value type with the TargetTypeName attribute, define the MaximumNumbers, MaximumIntegerNumbers, MaximumDecimalNumbers or the Negative or Positive Sign. Note this control can be used inside a FreeForm control we say previously.

<cfe:NumericTextBox ID="NumericTextBox1" runat="server" Value='<%# Bind("NumberOfEmployees") %>' TargetTypeName="System.Int32" />

There is also associated DataControlField, NumericTextField CodeFluent.Runtime.Web.UI.WebControls.NumericTextField) fields controls that you can use in GridView, DetailsView, etc.

<cfe:NumericTextField DataField="Age" HeaderText="Age" TargetTypeName="System.Int32"/>

Captcha Control
The Captcha control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaControl) displays an image with some simple text inside, but supposedly quite difficult to read for machines. You can define the image size, the complexity of the produced image, and a timeout duration. Notice that the image is generated by the BinaryLargeObjectHttpHandler of CodeFluent Entities (Learn more about Blob here).

The Captcha control comes with its validator, the CaptchaValidator control (CodeFluent.Runtime.Web.UI.WebControls.CaptchaValidator). As any validator, you just need to declare the ControlToValidate and the CaptchaControlID associated.

In this example, we just display a message if the text entered corresponds to what was generated by the Captcha control.

<cfe:CaptchaControl ID="CaptchaControl1" runat="server" Width="200px" Height="50px" Expiration="120"
    Options="FontWarpFactorMedium, BackgroundNoiseLevelHigh,LineNoiseLevelHigh" />
<br />
Please enter the code or press F5 to refresh the browser
<br />
<cfe:CaptchaValidator ID="CaptchaValidator1" runat="server" ControlToValidate="Verify" CaptchaControlID="CaptchaControl1"
    SetFocusOnError="True" ErrorMessage="The code doesn’t match or there was a timeout" ForeColor="Red" />
<br />
<asp:TextBox ID="Verify" runat="server" EnableViewState="False" AutoCompleteType="None" />
<asp:Button ID="btValidate" runat="server" Text="Validate" OnClick="btValidate_Click" /><br />
<asp:Label ID="lblResult" runat="server" Text="You enter the correct text! Thank you for validating." Visible="false" ForeColor="Green"/>

In the button Click event, call Page.IsValid to validate the captcha:

<script runat="server">
    protected void btValidate_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            lblResult.Visible = true;
        }
        else
        {
            lblResult.Visible = false;
        }
    }
</script> 

Have a look at the Captcha image here:

Captcha

As you’ve seen in this serie, CodeFluent.Runtime.Web can be very useful to us, web developers who are tired to write a lot of code-behind to do simple actions. With these controls you just need to drag and drop them on your page, save and enjoy.

These controls are located in the CodeFluent.Runtime.Web assembly, part of the CodeFluent Entities product ! Try them!

Happy controling!

The R&D team.

Multi-database architecture with CodeFluent Entities

January 29, 2014 1 comment

In this article, we’ll see how to use multiple stores in your CodeFluent Entities application. In a previous post, we explained that the Modeler doesn’t provide a “Store Name” property in the producer’s configuration property grid. It’s now fully supported in the product so you don’t need to modify your XML parts by hand.

However, before we go any further, let’s bring some theory. The CodeFluent Entities “store” concept can be seen as a virtual storage unit and is mainly used by the persistence layer producers. Your CodeFluent Entities model contains by default one store which is always visible in your model, in the Visual Studio’s solution explorer tree view:

If you need to add a new Store, right-click on the “Stores” node and select “Add new Store”. Simply choose a name and your application now contains two stores: CarRental and CarRentalReferential.

Okay, great… but why would I want to do this?

When you develop an application, you may feel the need to dispatch your tables (inferred from model entities) in more than one database. For example, I want to create the Customer table in the CRM Database, and the Product table in the Master Data Database. Well, this is exactly why the store concept exists. Another example is shown here in this diagram:

Multidatabase Architecture with CodeFluent Entities

Now, how to configure the “City”, “Address” and “Country” entities so their inferred tables will be generated to the CarRental database? It’s very easy : just select each of them, open the Properties window (F4), select the property grid Advanced tab (pointed by the red arrow below), and specify the target store like this:

Then you can define two persistence producers in your project and assign each of them a specific store:

Now don’t forget to configure your store and set it a specific connectionString. By building your model, CodeFluent Entities will generate the code corresponding to each store. The right things in the right places ;) !

Store SQL result

To conclude, I’d like to point out that, by design and by default, you can’t create model-level relationships between entities from different stores. Databases could be located in different servers or in different storage systems. But if you know what you’re doing, and still need this, you can change this default behavior by setting the allowCrossStoreRelations attribute on your project.

Happy Storing!

Antoine Diekmann

Exploring the CodeFluent Runtime: Web Controls – Part 1

January 28, 2014 1 comment

Today, on the series “Exploring the CodeFluent Runtime” we’re going to explore the ASP.Net Web Controls inside the CodeFluent.Runtime.Web namespace. This is all provided as part of CodeFluent Entities.

In the CodeFluent.Runtime.Web assembly, you’ll find several controls usable in ASP.Net WebForms applications. The first we’ll see are controls used to render UI relatively to the data (bindings).

BooleanControl (CodeFluent.Runtime.Web.UI.WebControls.BooleanControl) displays what’s defined in FalseTemplate or TrueTemplate according to a boolean value.

<cfe:BooleanControl ID="BooleanControl1" runat='server' Value='<%# Eval("MyBooleanValue") %>' AutoBind="true">
    <TrueTemplate>
        This template will be displayed if Value is evaluated as "true"
    </TrueTemplate>
    <FalseTemplate>
        This template will be displayed if Value is evaluated as "false"
    </FalseTemplate>
</cfe:BooleanControl>

CompareControl (CodeFluent.Runtime.Web.UI.WebControls.CompareControl) displays FalseTemplate or TrueTemplate according to what’s defined by the ValueToCompare attribute and an Operator (Equal, NotEqual,
GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, DataTypeCheck). For the DataTypeCheck operator, the ValueToCompare will be the full name of the type to check.

<cfe:CompareControl ID="CompareControl1" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="GreaterThan" ValueToCompare="0">
    <TrueTemplate>
        Value is greater than 0
    </TrueTemplate>
    <FalseTemplate>
        Value is less than or equal to 0
    </FalseTemplate>
</cfe:CompareControl>
 
<cfe:CompareControl ID="CompareControl2" runat='server' Value='<%# Eval("MyValueToCompare") %>' Operator="DataTypeCheck" ValueToCompare="System.Int32">
    <TrueTemplate>
        Value is a System.Int32
    </TrueTemplate>
    <FalseTemplate>
        Value is not a System.Int32
    </FalseTemplate>
</cfe:CompareControl>

MultiCompareControl (CodeFluent.Runtime.Web.UI.WebControls.MultiCompareControl) is similar to the CompareControl but is more like a switch.

<cfe:MultiCompareControl ID="MultiCompareControl1" runat="server" Value='<%#Eval("MyValueToMultiCompare") %>'>               
    <case ValueToCompare="10" Operator="GreaterThan">
            Value is greater than 10
    </case>
    <case ValueToCompare="0">
    Value is equal to 0
    </case>
    <default>
    Value is not equal to 0 and is less than or equal to 10
    </default>
</cfe:MultiCompareControl>

ExistsControl (CodeFluent.Runtime.Web.UI.WebControls.ExistsControl) displays FalseTemplate or TrueTemplate depending on a given value. The value is tested against “null”, “DBNull”, or an empty string (possibly trimmed).

<cfe:ExistsControl ID="ExistsControl1" runat='server' Value='<%# Eval("Email") %>' Trim="true">
    <TrueTemplate>
        This template is displayed only if Value is not null or empty 
    </TrueTemplate>
    <FalseTemplate>
        This template is displayed when Value is null
    </FalseTemplate>
</cfe:ExistsControl>

When you work with enumerations into your Model, you want to be able to display and edit them easily into your forms or GridView. We have a solution for you! Let me introduce the Enum Controls.

EnumCheckBoxList (CodeFluent.Runtime.Web.UI.WebControls.EnumCheckBoxList) derives from the standard CheckBoxList control but is automatically filled with the fields of the enumeration type you define EnumTypeName parameter. Note this also supports multi-valued enumerations (with a [Flags] custom attribute).

EnumRadioButtonList (CodeFluent.Runtime.Web.UI.WebControls.EnumRadioButtonList) derives from the standard RadioButtonList control. As the EnumCheckBox, you only need to define the EnumTypeName attribute

EnumDropDownList (CodeFluent.Runtime.Web.UI.WebControls.EnumDropDownList) derives from the standard DropDownList and works the same way.

Another control that allows you to quickly bind your data is the BoolControl (CodeFluent.Runtime.Web.UI.WebControls.BoolControl). The BoolControl is a visual custom control that displays a System.Boolean or Nullable<System.Boolean> bound value. Depending whether the value is nullable or not, it can display a True/False or True/False/Undefined visual. It can use a CheckBox, DropDownList, horizontal button list, ListBox or horizontal or vertical radio button list to display these 2 or 3 items. It also supports read-only rendering and custom texts, interesting for localization purposes.

Is Customer:

<cfe:BoolControl ID="BoolControl1" runat="server" Value='<%# Bind("IsCustomer") %>' TrueText="Yes" FalseText="No" UnspecifiedText="Undefined" BoolControlType="HorizontalRadioButtonList" />

Contact Method:

<cfe:EnumCheckBoxList ID="EnumCheckBoxList1" runat="server" Value='<%# Bind("MethodToContact") %>' EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
Origin (RadioButton):
<cfe:EnumRadioButtonList ID="EnumRadioButtonList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
Origin (DropDown):
<cfe:EnumDropDownList ID="EnumDropDownList1" runat="server" Value='<%# Bind("Origin") %>' EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />           

Here is the result:

For each of these controls, an associated DataControlField exists so you can use them in GridView, DetailsView, etc.

<cfe:BoolField DataField="IsCustomer" HeaderText="Is Customer" TrueText="Yes" FalseText="No" BoolControlType="DropDownList" />
<cfe:EnumCheckBoxListField DataValueField="MethodToContact" HeaderText="Contact method" EnumTypeName="BlogCFE.ContactManager.ContactMethod" />
<cfe:EnumRadioButtonListField DataValueField="Origin" HeaderText="Origin (RadioButton)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />
<cfe:EnumDropDownListField DataValueField="Origin" HeaderText="Origin (DropDown)" EnumTypeName="BlogCFE.ContactManager.ContactOrigin" />        

the result in a grid view:

List of Contacts

As you’ve seen, these controls can avoid you to write a lot of code focusing more on a declarative way of programming.

In the next article, we’ll introduce the DataSources controls and another couple of cool utilities.

The R&D team.

Exploring the CodeFluent Runtime: Country utilities

January 21, 2014 1 comment

The CodeFluent.Runtime.Utilities.Country class is a cool tool that provides information about countries, regions, geographic locations and currencies.

Below is a figure showing a WPF application with a DataGrid that contains a list of countries with the information this class provides: locale identifier, region, english name, native name (in the corresponding language), currencies, etc.)

Country

XAML :

<Grid>
    <DataGrid x:Name="MyDataGrid" />
</Grid>

C# :

MyDataGrid.ItemsSource = CodeFluent.Runtime.Utilities.Country.AllCountries;

By running the code above, you’ll get a list of countries as a data source for your WPF DataGrid.

The Country object also exposes some useful methods such as:

GetCountry : find a country by its ISO-3166 two-letter code

CodeFluent.Runtime.Utilities.Country.GetCountry("AL")

It also supports principal subdivisions (e.g., provinces or states) of all countries coded in ISO 3166 so you can get locations and not only countries:

// *private joke* Carl, this one's for you !
var guadeloupe = CodeFluent.Runtime.Utilities.Country.GetCountry("GL");

// Get all locations installed on your system.
var allLocations = CodeFluent.Runtime.Utilities.Country.AllLocations;

GetCurrencyCountries : find countries for a given ISO currency symbol

var euroCountries = CodeFluent.Runtime.Utilities.Country.GetCurrencyCountries("EUR")

So here is the same grid with the list of countries that use EURO currency:

Country

Before leaving this topic, I suggest you have also have a look at the CultureComboBox control available in the CodeFluent.Runtime.Design namespace. It provides an associated Winforms ComboBox specialized for displaying countries.

The CodeFluent Runtime is  available with the full CodeFluent Entities product and with the CodeFluent Runtime Client 100% free assembly (available directly from Nuget).

Happy countrying!

The R&D team.

Follow

Get every new post delivered to your Inbox.

Join 41 other followers