Archive

Author Archive

Visual Studio Community 2013

November 17, 2014 Leave a comment

Visual Studio Community 2013 is a new, full-featured, and FREE addition to the Visual Studio product lineup.

We are thrilled to announce that CodeFluent Entities runs great on it!

Visual Studio 2013 Community Edition

You can learn more about the new features of Visual Studio Community 2013 here:

You can download the latest version of CodeFluent Entities here, or update your version using the Licensing tool. Remember that you can follow the latest new features and bug fixes of CodeFluent Entities subscribing to this RSS.

Happy downloading,

The R&D Team

Categories: News Tags: ,

Exploring the CodeFluent Runtime: Convert utilities

November 3, 2014 Leave a comment

Today, on the series Exploring the CodeFluent Runtime,  we are going to explore the useful ConvertUtilities class from the CodeFluent.Runtime or CodeFluent.Runtime.Client assembly.

First of all you need to reference the dll in your project and include the directive as follow:

using CodeFluent.Runtime.Utilities;

The CodeFluent.Runtime is a part of the CodeFluent Entities product or you can download the following nuget package.

ChangeType

Returns an instance of type T whose value is equivalent to a specified input object. If an error occurs, a computed default value of type T will be returned.

var convert1 = ConvertUtilities.ChangeType<int>("42");
// –> 42
ConvertUtilities.ChangeType<bool>("yes"); // –> True
ConvertUtilities.ChangeType<bool>("y"); // –> True
ConvertUtilities.ChangeType<bool>("1"); // –> True
ConvertUtilities.ChangeType<CultureInfo>(1036); // –> CultureInfo("fr-fr")
ConvertUtilities.ChangeType("10/30/2014", DateTime.Now, new CultureInfo("en-US")); // –> 'October  30<sup>Th</sup> 2014' fr-FR
ConvertUtilities.ChangeType("Monday, Tuesday Wednesday | 8", DayOfWeek.None); // –>  Monday | Tuesday | Wednesday | Thursday
// Available separators: space, comma, pipe

SetCurrentThreadCulture

Sets the current thread culture. Handles integer values as lcid (http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx)

ConvertUtilities.SetCurrentThreadCulture("fr-FR");
ConvertUtilities.SetCurrentThreadCulture(1036);
ConvertUtilities.SetCurrentThreadCulture("1036");

Decamelize
Decamelizes the specified text using default decamelization options.

ConvertUtilities.Decamelize("ProductName"); // –> "Product Name"
ConvertUtilities.Decamelize("ProductName", ConvertUtilities.DecamelizeOptions.ForceRestLower); // –> "Product name"

Evaluate

Evaluates the specified expression on a given container object (like Eval in Asp.Net WebForm). In case of an error, the defaultValue parameter will be returned.

ConvertUtilities.Evaluate(DateTime.Now, "TimeOfDay.Hours", typeof(int), defaultValue: 0); // –> 15 (depends of your time<span style="font-family:Wingdings;">J</span> )
ConvertUtilities.Evaluate(DateTime.Now, "TimeOf", typeof(int), defaultValue: 0);  // –> 0
ConvertUtilities.Evaluate(null, "TimeOfDay.Hours", typeof(int), defaultValue:  0); // –> 0 

ConcatenateCollection

Concatenates a collection into a string using a separator character. An expression is ran on each object in the collection using ASP.NET DataBinding syntax style.

List<DateTime> collection = new List<DateTime>
{
   new DateTime(2007, 10, 10),
   new DateTime(2010, 10, 10),
   new DateTime(2014, 10, 10)
};

ConvertUtilities.ConcatenateCollection(collection, "Year", " - "); //- > "2007 - 2010 - 2014"

FormatFileSize

Format file size in bytes to the correct unit.

ConvertUtilities.FormatFileSize(399960003); // –>  381,43 MB
ConvertUtilities.FormatFileSize(399960003, null, "N5", new CultureInfo("en-US")); // –> 381.43158 MB

FromFileExtension

Converts a file extension to the corresponding image format.

ConvertUtilities.FromFileExtension(".jpg"); // –> ImageFormat.Jpeg
ConvertUtilities.FromFileExtension("png"); // –> ImageFormat.Png

IsFlagsEnum

Determines whether the specified enum type has the Flags attribute.

Note: you can use Enum.HasFlag with .Net Framework 4.0 and higher.

ConvertUtilities.IsFlagsEnum(typeof(FileOptions)); // –> true 

GetMaxValue

Gets the maximum value for a given type.

ConvertUtilities.GetMaxValue(typeof(int)); // –> 2147483647 
ConvertUtilities.GetMaxValue(typeof(DateTime));// –> {12/31/9999 23:59:59}

GetUniqueName

Get a name guaranteed not to be in a given a list of names. This method appends numbers to a preferred name.

List<string> names = new List<string>
"Gérald",
"Alexandra",
"Lionel",
"Marc"
};
ConvertUtilities.GetUniqueName(names, "lionel", StringComparison.InvariantCultureIgnoreCase); // –>  lionel2
ConvertUtilities.GetUniqueName(names, "john", StringComparison.InvariantCultureIgnoreCase); // –> john

Nullify

Nullifies the specified string.

ConvertUtilities.Nullify("Windows", trim: true);// –> Windows
ConvertUtilities.Nullify("   ", trim: true);// –> Null
ConvertUtilities.Nullify("   ", trim: false);// –> "  "

RemoveDiacritics

Removes diacritics (accents) from a text.

ConvertUtilities.RemoveDiacritics("éàèçàöâ"); // –> eaecaoa

SplitToList

Splits a text into a collection of typed objects. Returned objects are automatically converted into the proper type if needed.

ConvertUtilities.SplitToList<int>("25,4,15,42", ',');// –> {25, 4, 15, 42}
ConvertUtilities.SplitToList<long>("255,TTT", ',');  // –>{255, 0} Takes the default values of Type 

ToHexa

Converts a byte array to its hexadecimal string representation.

ConvertUtilities.ToHexa(new byte[] {0x43, 0x6F, 0x64, 0x65});// –> "436F6465"

ToHexaDump

Converts a string to its hexadecimal dump representation.

ConvertUtilities.ToHexaDump("CodeFluent Entities");
//Offset    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF
//--------  -----------------------------------------------  ----------------
//00000000  43 00 6F 00 64 00 65 00 46 00 6C 00 75 00 65 00  C.o.d.e.F.l.u.e.
//00000010  6E 00 74 00 20 00 45 00 6E 00 74 00 69 00 74 00  n.t. .E.n.t.i.t.
//00000020  69 00 65 00 73 00                                i.e.s.
ConvertUtilities.ToHexaDump(new byte[] {0x43, 0x6F, 0x64, 0x65});
//Offset    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF
//--------  -----------------------------------------------  ----------------
//00000000  43 6F 64 65                                      Code

As you’ve seen in this article, ConvertUtilities can be very useful for .Net developers.

Happy Converting!

The R&D Team

Target Name Transformation aka TNT

October 10, 2014 Leave a comment

CodeFluent Entities allows you to write RAW methods. Using the name of a table or a column in a RAW method is not safe. Indeed CodeFluent Entities allows to define its own naming convention. So if you write the name of a column in a raw method and then you change the naming convention of your project, your method won’t work anymore.

To handle this case, CodeFluent Entities introduce Target Name Transformation (aka TNT). In a Raw method you can refers to a column by using for example “$Customer::DateOfBirth$”. This will be replaced by CodeFluent Entities by the name of the column corresponding to the property “DateOfBirth” of the entity “Customer”.

TNT supports the following syntaxes:

  • $[EntityName]$ corresponds to the table name,
  • $[PropertyName]$ corresponds to the property name,
  • $[EntityName]::[PropertyName]$ corresponds to the column name,
  • $[EntityName]:[ViewName]$ corresponds to the view name,
  • $[EntityName]:[ViewName]:[PropertyName]$ corresponds to a column name in the defined view,
  • $[Namespace].[EnumerationName].[EnumerationValue]$ corresponds to the enumeration value of an enumeration declared in the model.

We already talk about all of this. So today I’ll show you more.

When you write “$[EntityName]::[PropertyName]$”, CodeFluent Entities find the property and write its persistence name. But you can also specify a format by using curly brackets. Format allows you to navigate in the CodeFluent Entities API and get the desired value. Here’s some examples:

$Customer{Columns}$

[Customer].[Customer_Id],[Customer].[Customer_Name],[Customer].[Customer_DateOfBirth],
[Customer].[_trackLastWriteTime],[Customer].[_trackCreationTime],
[Customer].[_trackLastWriteUser],[Customer].[_trackCreationUser],
[Customer].[_rowVersion] 

$Customer:CustomView{Columns}$

[vCustomerCustomView].[Customer_Id],[vCustomerCustomView].[Customer_Name],
[vCustomerCustomView].[_rowVersion],[vCustomerCustomView].[_trackCreationTime],
[vCustomerCustomView].[_trackLastWriteTime],[vCustomerCustomView].[_trackCreationUser],
[vCustomerCustomView].[_trackLastWriteUser]

$Customer{TrackCreationUserColumn.FullName}$

[Customer].[_trackCreationUser]

$Customer{TrackLastWriteUserColumn.FullName}$

[Customer].[_trackLastWriteUser]

$Customer{TrackCreationTimeColumn.FullName}$

[Customer].[_trackCreationTime]

$Customer{TrackLastWriteTimeColumn.FullName}$

[Customer].[_trackLastWriteTime]

$Customer{RowVersionColumn.FullName}$

[Customer].[_rowVersion]

$Customer{TypeNameColumn.FullName}$

[Customer].[_typeName]

$Customer{Schema}$

Sample

$Customer{Entity.Properties.Count}$

3

$Customer{Columns[0].Name}$

Customer_Id

$Customer{Entity.Properties[“Name”].Column.Name}$

Customer_Name

$FirstName{Name}$

FirstName

$Customer::Name{DefaultValue}$

John Doe

$Customer::Id{FullPersistenceName}$

[Customer].[Customer_Id]

$Customer:CustomView:FirstName{Expression}$

FirstName

$Customer{Procedures[“Customer_Load”].FullName}$

[Customer_Load]

To find all possible formats, open Visual Studio Object Browser (Menu / View / Object Browser), and add “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler\CodeFluent.Model.dll” and look at properties of classes:

  • CodeFluent.Model.Persistence.Table
  • CodeFluent.Model.Property
  • CodeFluent.Model.Persistence.View
  • CodeFluent.Model.ViewProperty
  • CodeFluent.Model.Enumeration
  • CodeFluent.Model.EnumerationValue

If you can’t figure how to get a specific information from your model, please ask your question on the forum.

Happy TNTing,

The R&D Team

CodeFluent Entities and ComponentOne

October 6, 2014 Leave a comment

CodeFluent Entities generates code which can be used easily with many third party component providers. We already show before how to use CodeFluent Entities with Syncfusion. Today we’ll see how easy it is to work with ComponentOne (C1) WPF components!

The sample application displays a list of users and their contacts using a ComponentOne DataGrid. Additionally you can export user list to Excel.

The solution contains 4 projects:

The CodeFluent Entities model is very simple:

The email has a validation rule to ensure you can only save a user with an invalid email address to the database.

The relation between User and Contact is configured to save contacts after user. This means that when you call User.Save, associated contacts are also saved. This functionality is very useful in a master-detail view as we are creating!

Now we can create the WPF application. Here’s the main part of the XAML:

<Window.Resources>
<!-- Convert blob to image -->
<design:BinaryLargeObjectValueConverter2 x:Key="BlobConverter"/>
</Window.Resources>

<Grid>

<c1:C1DataGrid x:Name="DataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
  <c1:C1DataGrid.Columns>
    <c1:DataGridImageColumn Binding="{Binding Photo, Converter={StaticResource BlobConverter}}" Header="Photo" IsReadOnly="True" />
    <c1:DataGridTextColumn Binding="{Binding FirstName}" Header="First name" />
    <c1:DataGridTextColumn Binding="{Binding LastName}" Header="Last name"  />
    <c1:DataGridTextColumn Binding="{Binding Email}" Header="Email"  />
    <c1:DataGridBoundColumn Binding="{Binding Contacts.Count}" Header="Contacts" IsReadOnly="True" />
  </c1:C1DataGrid.Columns>

  <!-- Handle validation using IDataErrorInfo (this will validate the Email property) -->
  <c1:C1ValidationBehavior.ValidationBehavior>
    <c1:C1ValidationBehavior/>
  </c1:C1ValidationBehavior.ValidationBehavior>

  <c1:C1DataGrid.RowDetailsTemplate>
    <DataTemplate>
      <StackPanel Orientation="Vertical">
        <TextBlock Text="Contacts" FontSize="14"/>

        <c1:C1DataGrid ItemsSource="{Binding Contacts}" AutoGenerateColumns="False" BeginningNewRow="C1DataGrid_BeginningNewRow">
          <c1:C1DataGrid.Columns>
            <c1:DataGridTextColumn Binding="{Binding FirstName}" Header="First name" />
            <c1:DataGridTextColumn Binding="{Binding LastName}" Header="Last name" />
          </c1:C1DataGrid.Columns>
        </c1:C1DataGrid>
      </StackPanel>
    </DataTemplate>
  </c1:C1DataGrid.RowDetailsTemplate>
</c1:C1DataGrid>

<Button Grid.Row="1" HorizontalAlignment="Left" Click="ButtonExportToExcel_OnClick">Export Users to Excel</Button>
<Button Grid.Row="1" HorizontalAlignment="Right" Click="ButtonSaveAll_OnClick">Save all</Button>

</Grid>

When the window is opened, we load all users:

private readonly UserCollection _userCollection;

public MainWindow()
{
  // Load all users and bind them to the grid
  _userCollection = UserCollection.LoadAll();

  this.DataContext = _userCollection;
}

To save all users and their contacts, we have to call SaveAll method:

private void ButtonSaveAll_OnClick(object sender, RoutedEventArgs e)
{
   // Thanks to the cascade save, contacts are also saved
   _userCollection.SaveAll();
}

When a contact is added, we have to set its User property with the selected user:

private void C1DataGrid_BeginningNewRow(object sender,
DataGridBeginningNewRowEventArgs e)
{
  var contact = e.Item as Contact;

  if (contact == null)
    return;

  var user = DataGrid.CurrentRow.DataItem as User;

  if (user != null)
  {
    contact.User = user;
  }
}

Finally we can export user collection to Excel:

private
void ButtonExportToExcel_OnClick(object sender, RoutedEventArgs e)
{
  DataGrid.Save("export.xlsx", FileFormat.Xlsx);
}

That’s it. With only a few lines of code, CodeFluent Entities and ComponentOne you can create a fully functional application.

The code sample is available on our GitHub repository: https://github.com/SoftFluent/CodeFluent-Entities/tree/master/Samples/SoftFluent.Samples.ComponentOne

Happy componenting,

The R&D Team

Getting started with the Blob Handler

October 6, 2014 Leave a comment

In ASP.NET, if you need to display a blob (Binary Large Object) such as an image, a video or a file, you’ll need to provide an URL to your display control. When storing blobs in database, a standard practice is to create a web page such as a blob.aspx to which you provide the blob’s id as parameter and which the page will load and display so that you can set your display control’s source to that URL.

Actually, CodeFluent Entities automatically generates a HTTP Handler which does all the work described before: thanks to it you’ll retrieve an URL pointing to your blob and which you’ll be able to use in your display controls.

To use it you need to register it in your web.config file as:

<system.web>
    <httpHandlers>
      <add verb="GET" path="blobhandler.ashx" 
type="<DefaultNamespace>.Web.HttpHandler, <DefaultNamespace>"/>
    </httpHandlers>
</system.web>

Or

<system.webServer>
    <httpHandlers>
      <add name="blobhandler" verb="GET" path="blobhandler.ashx"
type="<DefaultNamespace>.Web.HttpHandler, <DefaultNamespace>" />
    </httpHandlers>
</system.webServer>

Blob handler output types

 

The blob handler allows to get blobs in different manners to fit with common usages.

  • Raw: Use for downloading a File
  • Image: Use for displaying an Image

  • Thumbnail: Display a thumbnail of the Image (you can specify the desired height and width)


  • FileExtension: Display the File icon base on its extension (the same icon as in Windows Explorer)

  • FileExtensionSmall: Display the small Fileicon base on its extension (the same icon as in Windows Explorer)

To build the URL, you can use:

  • HttpHandler.BuildUrl(…)
  • BaseBinaryLargeObject.BuildHttpHandlerUrl(…)
  • ASP.Net controls: BinaryLargeObjectControl, BlobControl and BinaryLargeObjectField (located in CodeFluent.Runtime.Web)

For instance:

customer.Photo.BuildHttpHandlerUrl(BinaryLargeObjectUrlType.Raw)
customer.Photo.BuildHttpHandlerUrl(BinaryLargeObjectUrlType.Image)

Securing the blob handler

 

If you want to prevent some users to access the blob handler and so download files, you can write your own validation logic:

  • Add a partial class “HttpHandler.partial.cs”:

  • Then override the ResponseWriteBlob method and add your logic:
partial class HttpHandler
{
protected override bool ResponseWriteBlob(CodeFluent.Runtime.BinaryServices.BinaryLargeObject blob)
  {
    // Only administrators can access the blob handler
    return this.CodeFluentContext.User.IsInRole("Administrator");
  }
}

Server and client cache

 

Moreover blobs can be cached on the server and on the client to relieve the database. This feature is activated by default.

  • Server cache: When loading a blob property using CodeFluent Entities, it actually loads it from the database the first time and stores it on the disk; consequently, next calls won’t load it back from database anymore, unless a modification was done on the blob which will reload it and update the cache.
  • Client cache: Usage of the “Last-Modified” and “If-Modified-Since” http headers so the client download blobs only once.

Read more details about blob caching at http://blog.codefluententities.com/2011/11/09/codefluent-entities-blob-cache/

Happy storing,

The R&D Team

Member Format Expression

September 29, 2014 Leave a comment

Using CodeFluent Entities, you can use “Member Format Expressions” to customize the way names of entities and properties are formatted. We’ve already written before about the member format expression:

Today I’ll share the property format expression I use everyday. By default entities display property name and optionally type name:

Let’s create a new property format expression. Click the “Property Format” menu Item / “Choose”. Click the “Add New” button and copy the following format expression:

<if condition=IsEntityDisplay>-> </if> <if condition=IsNullable>({Name})<else />{Name}</if> : {DisplayTypeName} <if condition=”‘true’=Element.GetAttribute(‘localizable’,’http://www.softfluent.com/codefluent/patterns/localization/2008/1&#8242;)”>(Localizable)</if> <if condition=Relations.Count>({CascadeDelete})</if>

Now entities look like:

  1. The icon indicates the property is a member of the primary key
  2. Parentheses indicate the property is nullable
  3. “(Localizable)” indicates the property is localizable when using the Localization aspect
  4. “->” indicates the property is the entity display name
  5. The icon indicates the property type is an enumeration
  6. “(None)”, “(Before)” or “(After)” indicates the selected Cascade Delete option of the relation
  7. “*” and the infinite symbol indicate the property type is a collection

Thanks to the extensibility of the CodeFluent Entities modeler you can customize your working environment to fit your need. With this property member format, you visualize lots of information about your model in a breeze. Can you do that without CodeFluent Entities?

Happy formatting !

The R&D Team

Export your model as image

September 26, 2014 Leave a comment

Do you know that it’s possible to save the current Surface display in an image file ? It’s the easy way to share your model with someone.

You just need to right-click somewhere in the selected surface. Then you’ll see a new contextual menu with the following command:

Many formats are supported: PNG, BMP, GIF, WDP, JPG, and TIFF.

Here are some examples:

Happy exporting,

The R&D Team.

Follow

Get every new post delivered to your Inbox.

Join 55 other followers