• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Thursday, 20 Mar 2008 13:05

I'm really happy to announce that starting from the build v1.5.8.37058, you can now write your own templates directly from Visual Studio 2008. You will then benefit from all the good Visual Studio features such as Intellisense, debugging, syntax coloration and so forth!

I have recorded a webcast to demonstrate how to install and use this new feature. You can find it in the Resources section of OlyMars Refresh portal. You will find below a screen shot of a table based template written inside Visual Studio 2008.

Enjoy!

 

TemplateInsideVisualStudio2008

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 13 Mar 2008 00:58

The Release Candidate 1 (RC1) of OlyMars Refresh has been released yesterday. It is now available on http://www.olymars.net

This build supports both SQL Server 2005 and SQL server 2008 (CTP6) as long as Visual Studio 2005 and Visual Studio 2008. If you want to test this version, please do go the OlyMars Refresh portal (http://www.olymars.net) and ask for an account to get access to the latest build.

RC1 = v1.5.7.33290

 

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 25 Oct 2006 13:54

I often need to add the source code content of a whole directory to my Visual Studio 2005 projects.

That's the case when I use OlyMars for my own developement projects. Usually, what I need is to add a link to the source files that have been generated by OlyMars. I want this as a link because I want to be sure that my custom projects using the generated code are always up to date even if I regenerate the code.

If you simply drag and drop a folder in Visual Studio 2005, an actual copy of the files is made, not a link to them. 

This is precisely why I have written a Visual Studio 2005 AddIn named Add Directory Content

To download the latest version of this FREE AddIn : http://www.msfrancedev.net/AddDirectoryContent/AddDirectoryContentSetup.msi

Once installed, its use is very very simple. First, open your Visual Studio project. Then, create a directory in your project structure which will host the linked files. You can skip this directory creation if you like. In this case, the files will be added to your project root. To run this AddIn, all you have to do is to go to your Visual Studio 2005 Tools menu and hit the Add Directory Content menu.

Then, locate the directory where your source code is stored. You can include the subdirectories by checking the corresponding CheckBox. This AddIn can also recreate the same folder structure in your Visual Studio 2005 project than in your actual directory. Finally, you can filter the files to be added to your projects.

At the end of the process, a quick summary is displayed.

You are done ! All the files were correctly added to your project and now, each time the original files are changed, your project will pickup the changes right away!

Note that if you try to add an existing file to your project, an error message will be generated. You can treat this as a simple warning. No harm here.

If you have any feedback on this AddIn, you can use the Comment section of this post.

Enjoy !

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 11 Oct 2006 00:25

I will finally be presenting OlyMars Refresh (v1.5) at TechEd Europe Developers 2006 in Barcelona, Spain in early November!

If you want to discover this .NET 2.0 code generator for SQL Server 2005 and you are in Barcelona for TechEd Europe 2006, feel free to attend this session.

Stay tuned for more details on this session.

[UPDATE] I have now more details on this session. This session code is DEV366 and I will be presenting OlyMars Refresh on Friday, November 10th, 2006 from 15:15 to 16:30. More details on the TechEd Europe Developers web site. This session title is: Boost Your Data-Driven Application Development Using SQL Server Centric .NET Code Generator [OlyMars Refresh]

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Friday, 29 Sep 2006 15:52
Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 17 Apr 2006 18:57

The first beta (Preview I) of OlyMars Refresh v1.5 is now available to beta participants.

Beta participants, if you are interested in testing this beta , just browse to the new OlyMars Refresh Portal located at:

http://www.olymars.net

From this portal, you will be able to download the latest builds and information on OlyMars Refresh v1.5

 

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Friday, 07 Apr 2006 19:51

It's time to give everyone a little update on where I am on this generator!

First, the version 2.0, code named "DroitAuBut" is currently scheduled to be ready around Orcas timeframe (Visual Studio 2005.vNext). Unfortunately, I don't have currently neither the resources nor the time to release anything serious before at least another 12 months.

That said, I don't want to let my customers down while SQL Server 2005 is now broadly available. As you might know, the current version of Olymars (v1.0) does not work on SQL Server 2005 because it relies on a deprecated system table.

The good news is that I'm currently working on a "Olymars Refresh" version (=> v1.5) which is Olymars v1.0 features only but working on SQL Server 2005.

Not to mention that this version is built using Visual Studio 2005 and is designed to generate .NET 2.0 compliant code.

I plan to release a beta next week. If you are interested in participating in this beta plan, please send me an email:

I will send you a private beta build when it is available.

Thanks for your continuous support!

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 22 Feb 2005 05:42

An issue has prevented users from downloading the latest build of OlyMars.

As a matter of fact, until 9:00 PM GTM+1 today, the latest.zip was unfortunately redirected to an old version of OlyMars [1.0.1697.21165]. If you have downloaded your build before 9PM GMT+1 today, please download again the latest build [1.0.1876.37304] by clicking here.

We are very sorry for any inconvenience.

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Sunday, 20 Feb 2005 06:37

I have posted a new build of OlyMars [1.0.1876.37304] that includes the brand new XML Web Services 2.0 AddOn.

You can download this build here (once unzipped, you will need to recreate the OlyMars repository).

XML Web Services AddOn:

  • You will find a slide deck describing this new AddOn:
    <OlyMars Directory>\AddOns\XML Web Service\Documentation.ppt
  • You can also download a video that describes how to reuse this new AddOn:
    http://www.olymars.net/XmlWebServicesVideo1.rar (37’28, WMV format, 55 MB compressed)

There have been also some minor bugs corrected in this release. Finally the "Check For Upgrade" feature is working again.

Any feedback can be redirected by email to olyfeed@microsoft.com

Enjoy!

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 11 Jan 2005 08:53

I have enhanced the support of Xml Web Services in OlyMars and I need some volunteers to help me on this before it goes public. Of course, the documentation for this new AddOn is not available yet but this is where it goes fun!

Like I said, I need volunteers to test and help write documentation for this stuff. If you are interested in helping me, please send me an email BY CLICKING on this link (so it can be correctly routed in my inbox).

Thanks for your continuous support!

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 08 Jul 2004 20:17

Arpajon Hospital (Essonne, France) - July 8th, 2004 - The Belaud Company announced officially today the availability of the version 2.0 (code named "Fanny") of its famous product line. As of today, no major blocking bug was discovered. This new release will allow Quentin, Christelle and Pascal to realize their full potential.

Availability and pricing
The release team has signoff for "RTM" (Release To Manufacturer) at 09:51AM (GMT+1). This “Standard” version will start at around 52 centimeters for 3,920 grams.

Launch event
You can expect an official launch event very soon. A new press release will be issued to keep you informed.

About Belaud Company
Officially founded the June 9th, 2001 (NASDAQ "BLD"), the Belaud Company is the worldwide leader in Belaud technology based products. The previous version (1.0, code named "Quentin") was officially released on May 4th, 2000

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Sunday, 27 Jun 2004 18:22

A bug was discovered by one of the OlyMars users (thanks to Benoit Fouletier). This bug is related to the "Business Component Layer" AddOn.

Let's say that we have a Product table related to a Category table; let's say the foreign key CategoryID in the Product table is NOT mandatory. If, for a given record, CategoryID is Null, incorrect behavior occurs in the Product class:

Product myProduct = new Product("...", myProductID)

if (myProduct.CategoryID.IsNull) {

    string categoryName = myProduct.Category.Name; // returns something (the first record of the table) instead of returning a Null reference

}

This bug was corrected in the latest build (1.0.1638.23471 or later). A NullReferenceException exception is now thrown if you try to access the myProduct.Category object whereas myProduct.CategoryID is System.Data.SqlTypes.SqlInt32.Null

You need to re import back the "Business Component Layer" AddOn and rebuild the corresponding AddIn (see <OlyMars Directory>\AddOns\Business Components Layer\Documentation.mht).

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 12 Jun 2004 23:20

OlyMars uses the SQL Server 2000 extended properties (read this for more information on Extended Properties) to store various metadata, among them, the namespaces to use during code generation.

You can now edit the default values directly from the "BuiltIn Templates" AddIn. As a consequence, those values are not going to be asked anymore during the first generation as it was the case before.

 

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 12 Jun 2004 06:14

Six new properties have been added to both the Table and Column objects.

Column object:

  • IsPrimaryOnlyKey: Returns True if the column is a primary key and not also a foreign key
  • IsForeignOnlyKey: Returns True if the column is a foreign key and not also a primary key

Table object:

  • HasPrimaryOnlyKey: Returns True if the table has at least one primary key that is not also a foreign key
  • PrimaryOnlyKeys: Returns the primary keys collection that are not also foreign keys of the current table
  • HasForeignOnlyKey: Returns True if the table has at least one foreign key that is not also a primary key
  • ForeignOnlyKeys: Returns the foreign keys collection that are not also primary keys of the current table

The product documentation has been updated.

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 09 Jun 2004 15:51

I have posted a new build with some enhancements and bug fixes. New features have been added to the "TreeNode Factory" AddOn (be sure to reimport the new version of this add-on into your repository).

Note that you should be familiar with this AddOn before reading this. If this is not the case, you can take a look at the documentation:
<OlyMars directory>\AddOns\TreeNodeFactory\Documentation.mht

Let's say that we have the following scenario:
- We would like to add a parent node named "Categories"
- We would like to add under this parent node all the categories of the database. Each time the user selects one of these nodes, he should see in the status bar the number of products of that category
- We would like to add under each category node all the related products. We would to see the name of the product, the price of that product and the current stock number. Furthermore, each time the product current stock is less than 50, we would like the node to be red; for stock between 50 and 300, we would like it to be orange. For stock above 300, the node should be green. Each time the user selects a product, he should see in the status bar the name of the main supplier of this product. Finally, we do not want to add all the products which price is between 1000 and 1100

To be able to handle this scenario, we will use the new features provided in the "TreeNode Factory" AddOn:
- A new StaticCustomTreeNode class
- Two new events : BeforeInsert and AfterInsert
- The ability to build dynamically both the Id and/or the Display to be used for each node by using the FormatIdDisplay event
- The ContextOfUse has been expanded from the string type to the more general object type allowing you to provide an enumeration instead of a string for example
- A Columns array is now available for each StoredProcedureTreeNode. You can retrieve back all the columns for each row returned by the stored procedure call

Here is an example on how to reuse those new features (you can download this code):

[Database]-----------------------------------------------------------------------------------------

CREATE TABLE [Category] (
 [CategoryID] uniqueidentifier,
 [CategoryName] [varchar] (255),
 CONSTRAINT [PK_Category] PRIMARY KEY ([CategoryID])
)

CREATE TABLE [Supplier] (
 [SupplierID] uniqueidentifier,
 [SupplierName] [varchar] (255),
 CONSTRAINT [PK_Supplier] PRIMARY KEY ([SupplierID])
)

CREATE TABLE [Product] (
 [ProductID] uniqueidentifier,
 [ProductName] [varchar] (255),
 [ProductCategoryID] [uniqueidentifier],
 [ProductPrice] [money],
 [ProductCurrentStock] [int],
 [ProductMainSupplierID] [uniqueidentifier],
 CONSTRAINT [PK_Product] PRIMARY KEY ([ProductID]),
 CONSTRAINT [FK_Product_Category] FOREIGN KEY ([ProductCategoryID]) REFERENCES [Category] ([CategoryID]),
 CONSTRAINT [FK_Product_Supplier] FOREIGN KEY ([ProductMainSupplierID]) REFERENCES [Supplier] ([SupplierID])
)

CREATE Procedure [spS_xTNF_Categories] As

Select
  CategoryID
, CategoryName
, (Select IsNull(Count(*), 0) From Product Where ProductCategoryID = CategoryID) As ProductsCount

From Category Order By CategoryName Asc

Return(@@RowCount)

CREATE Procedure [spS_xTNF_Products] (@CategoryID uniqueidentifier) As

Select
  ProductID
, ProductName
, ProductPrice
, ProductCurrentStock
, SupplierName

From Product Left Outer Join Supplier On ProductMainSupplierID = SupplierID

Where ProductCategoryID = @CategoryID Order By ProductName Asc

[C#.NET]-----------------------------------------------------------------------------------------

using System.Data.SqlTypes;
using SPs = DemoTNF.DataClasses.StoredProcedures;
using DemoTNF.Windows.TreeNodeFactory;
using SP_TNF = DemoTNF.Windows.TreeNodeFactory.StoredProcedureTreeNodeFactory;

public FormStart() {
 //
 // Required for Windows Form Designer support
 //
 InitializeComponent();

 //
 // TODO: Add any constructor code after InitializeComponent call
 //
 Init();
}

private void Init() {

 // Let's decide once for good how to connect to the back end database
 SP_TNF.SetUpConnection(string.Empty);

 // We want to handle the following three events:
 // FormatIdDisplay, BeforeInsert and AfterInsert
 SP_TNF.FormatIdDisplay += new FormatIdDisplayHandler(SP_TNF_FormatIdDisplay);
 SP_TNF.BeforeInsert += new BeforeInsertHandler(SP_TNF_BeforeInsert);
 SP_TNF.AfterInsert += new AfterInsertHandler(SP_TNF_AfterInsert);


 // Let's create a Parent TreeNode to hold all the categories
 // Let's use a StaticCustomTreeNode for this
 StaticCustomTreeNode categories = new StaticCustomTreeNode(
             MyContextOfUse.Categories
           , null
           , "Categories"
           , true);
 treeView1.Nodes.Add(categories);
}

private enum MyContextOfUse {

 Categories, Category, Product
}

private void treeView1_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e) {

 // Let's get the node being expanded
 ITreeNodeFactoryCustomTreeNode currentNode =
      e.Node as ITreeNodeFactoryCustomTreeNode;

 // If this node is not a node coming from the TreeNodeFactory
 // or if this node is already UpToDate, do nothing
 if (currentNode == null || currentNode.IsUpToDate) return;

 // Depending on the context of use of the current node,
 // let's do the right thing
 switch ((MyContextOfUse)currentNode.ContextOfUse) {

  // If we are expanding the categories node, let's
  // fill this node with all the categories. We are going
  // to call spS_xTNF_Categories stored procedure for this
  case MyContextOfUse.Categories:
   SP_TNF.Fill_spS_xTNF_Categories(
     currentNode.Nodes // this is the Nodes collection to fill
    , MyContextOfUse.Category // this is the context of use of the nodes being added
    , true // yes I want to purge the Nodes collection
    , true // yes I want to add a sub node to all the added nodes
    , SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryID.ColumnIndex // this is the column index of the primary key
    , SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryName.ColumnIndex // this is the index of the column to be use for display
    , true // I want to get track of all columns for each row
    );
   break;

  // If we are expanding a category node, let's
  // fill this node with all the related products. We are going
  // to call spS_xTNF_Products stored procedure for this
  case MyContextOfUse.Category:
   SP_TNF.Fill_spS_xTNF_Products(
     currentNode.Nodes // this is the Nodes collection to fill
    , MyContextOfUse.Product // this is the context of use of the nodes being added
    , true // yes I want to purge the Nodes collection
    , false // no I do not want to add a sub node to the added nodes
    , (Guid)currentNode.Id // This is the value to use for the @CategoryID stored procedure parameter
    , SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductID.ColumnIndex // this is the column index of the primary key
    , -1 // We do not want to use one specific column for the display but rather be called in the FormatdDisplay event to format this display
    , true // I want to get track of all columns for each row
    );
   break;
 }

 // Let's specify that this node is UpToDate now
 currentNode.IsUpToDate = true;
}

private void SP_TNF_FormatIdDisplay(object sender, StoredProcedureFactoryFormatIdDisplayEventArgs e) {

 switch ((MyContextOfUse)e.Node.ContextOfUse) {

  // Let's decide how to format the display for our products
  // All the row columns are available via e.Node.Columns[]
  case MyContextOfUse.Product:
   SqlString productName = (SqlString)e.Node.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductName.ColumnIndex];
   SqlMoney productPrice = (SqlMoney)e.Node.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductPrice.ColumnIndex];
   SqlInt32 productCurrentStock = (SqlInt32)e.Node.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductCurrentStock.ColumnIndex];

   e.Display = string.Format("{0} ({1:c}, {2:### ##0} in stock)", productName.Value, productPrice.Value, productCurrentStock.Value);
   break;
 }
}

private void SP_TNF_BeforeInsert(object sender, StoredProcedureFactoryBeforeInsertEventArgs e) {

 switch ((MyContextOfUse)e.Node.ContextOfUse) {

  // We don't want to see all products which prices are greater
  // than 1 000 and less than 1 100
  case MyContextOfUse.Product:
   SqlMoney productPrice = (SqlMoney)e.Node.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductPrice.ColumnIndex];

   e.Cancel = (productPrice.Value >= 1000m && productPrice.Value < 1100m);
   break;
 }
}

private void SP_TNF_AfterInsert(object sender, StoredProcedureFactoryAfterInsertEventArgs e) {

 switch ((MyContextOfUse)e.Node.ContextOfUse) {

  // We would like to set some color to the products nodes
  // Red for the products which current stock is less than 50
  // Orange for the products which current stock is greater than 50 and less than 300
  // Green for the products which current stock is greater than 300
  case MyContextOfUse.Product:
   SqlInt32 productCurrentStock = (SqlInt32)e.Node.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductCurrentStock.ColumnIndex];

   if (productCurrentStock.Value < 50) {

    e.Node.ForeColor = Color.Red;
   }
   else if (
     productCurrentStock.Value >= 50
     && productCurrentStock.Value < 300
     ) {

    e.Node.ForeColor = Color.Orange;
   }
   else {

    e.Node.ForeColor = Color.Green;
   }
   break;
 }
}

private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) {

 StoredProcedureCustomTreeNode currentNode = e.Node as StoredProcedureCustomTreeNode;
 if (currentNode == null) return;

 switch ((MyContextOfUse)currentNode.ContextOfUse) {

  case MyContextOfUse.Category:
   SqlInt32 productsCount = (SqlInt32)currentNode.Columns[SPs.spS_xTNF_Categories.Resultset1.Fields.Column_ProductsCount.ColumnIndex];
   statusBar1.Text = string.Format("This category has {0} products", productsCount.Value);
   break;

  case MyContextOfUse.Product:
   SqlString supplierName = (SqlString)currentNode.Columns[SPs.spS_xTNF_Products.Resultset1.Fields.Column_SupplierName.ColumnIndex];
   statusBar1.Text = supplierName.IsNull ? "No supplier" : string.Format("Main supplier for this product is: {0}", supplierName.Value);
   break;
 }
}

[VB.NET]-----------------------------------------------------------------------------------------
Imports System.Data.SqlTypes
Imports SPs = DemoTNF.DataClasses.StoredProcedures
Imports DemoTNF.Windows.TreeNodeFactory
Imports SP_TNF = DemoTNF.Windows.TreeNodeFactory.StoredProcedureTreeNodeFactory

Public Sub New()
 MyBase.New()

 'This call is required by the Windows Form Designer.
 InitializeComponent()

 'Add any initialization after the InitializeComponent() call
 Init()
End Sub

Private Enum MyContextOfUse

 Categories
 Category
 Product

End Enum

Private Sub Init()

 ' Let's decide once for good how to connect to the back end database
 SP_TNF.SetUpConnection(String.Empty)

 ' We want to handle the following three events:
 ' FormatIdDisplay, BeforeInsert and AfterInsert
 AddHandler SP_TNF.FormatIdDisplay, New FormatIdDisplayHandler(AddressOf SP_TNF_FormatIdDisplay)
 AddHandler SP_TNF.BeforeInsert, New BeforeInsertHandler(AddressOf SP_TNF_BeforeInsert)
 AddHandler SP_TNF.AfterInsert, New AfterInsertHandler(AddressOf SP_TNF_AfterInsert)


 ' Let's create a Parent TreeNode to hold all the categories
 ' Let's use a StaticCustomTreeNode for this
 Dim categories As New StaticCustomTreeNode( _
          MyContextOfUse.Categories _
        , Nothing _
        , "Categories" _
        , True)

 TreeView1.Nodes.Add(categories)
End Sub

Private Sub SP_TNF_FormatIdDisplay(ByVal sender As Object, ByVal e As StoredProcedureFactoryFormatIdDisplayEventArgs)

 ' Let's decide how to format the display for our products
 ' All the row columns are available via e.Node.Columns[]
 Select Case CType(e.Node.ContextOfUse, MyContextOfUse)

  Case MyContextOfUse.Product
   Dim productName As SqlString = CType(e.Node.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductName.ColumnIndex), SqlString)
   Dim productPrice As SqlMoney = CType(e.Node.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductPrice.ColumnIndex), SqlMoney)
   Dim productCurrentStock As SqlInt32 = CType(e.Node.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductCurrentStock.ColumnIndex), SqlInt32)

   e.Display = String.Format("{0} ({1:c}, {2:### ##0} in stock)", productName.Value, productPrice.Value, productCurrentStock.Value)

 End Select

End Sub

Private Sub SP_TNF_BeforeInsert(ByVal sender As Object, ByVal e As StoredProcedureFactoryBeforeInsertEventArgs)

 ' We don't want to see all products which prices are greater
 ' than 1 000 and less than 1 100
 Select Case CType(e.Node.ContextOfUse, MyContextOfUse)

  Case MyContextOfUse.Product
   Dim productPrice As SqlMoney = CType(e.Node.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductPrice.ColumnIndex), SqlMoney)
   e.Cancel = productPrice.Value >= 1000 And productPrice.Value < 1100

 End Select

End Sub

Private Sub SP_TNF_AfterInsert(ByVal sender As Object, ByVal e As StoredProcedureFactoryAfterInsertEventArgs)

 ' We would like to set some color to the products nodes
 ' Red for the products which current stock is less than 50
 ' Orange for the products which current stock is greater than 50 and less than 300
 ' Green for the products which current stock is greater than 300
 Select Case CType(e.Node.ContextOfUse, MyContextOfUse)

  Case MyContextOfUse.Product
   Dim productCurrentStock As SqlInt32 = CType(e.Node.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductCurrentStock.ColumnIndex), SqlInt32)

   If productCurrentStock.Value < 50 Then

    e.Node.ForeColor = Color.Red

   ElseIf productCurrentStock.Value >= 50 And productCurrentStock.Value < 300 Then

    e.Node.ForeColor = Color.Orange

   Else

    e.Node.ForeColor = Color.Green

   End If

 End Select

End Sub

Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand

 ' Let's get the node being expanded
 Dim currentNode As ITreeNodeFactoryCustomTreeNode = _
     CType(e.Node, ITreeNodeFactoryCustomTreeNode)

 ' If this node is not a node coming from the TreeNodeFactory
 ' or if this node is already UpToDate, do nothing
 If currentNode Is Nothing Or currentNode.IsUpToDate Then Return

 ' Depending on the context of use of the current node,
 ' let's do the right thing
 Select Case CType(currentNode.ContextOfUse, MyContextOfUse)

  ' If we are expanding the categories node, let's
  ' fill this node with all the categories. We are going
  ' to call spS_xTNF_Categories stored procedure for this
 Case MyContextOfUse.Categories
   SP_TNF.Fill_spS_xTNF_Categories( _
         currentNode.Nodes _
       , MyContextOfUse.Category _
       , True _
       , True _
       , SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryID.ColumnIndex _
       , SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryName.ColumnIndex _
       , True _
       )
   ' currentNode.Nodes: this is the Nodes collection to fill
   ' MyContextOfUse.Category: this is the context of use of the nodes being added
   ' true: yes I want to purge the Nodes collection
   ' true: yes I want to add a sub node to all the added nodes
   ' SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryID.ColumnIndex: this is the column index of the primary key
   ' SPs.spS_xTNF_Categories.Resultset1.Fields.Column_CategoryName.ColumnIndex: this is the index of the column to be use for display
   ' true: I want to get track of all columns for each row

   ' If we are expanding a category node, let's
   ' fill this node with all the related products. We are going
   ' to call spS_xTNF_Products stored procedure for this
  Case MyContextOfUse.Category
   SP_TNF.Fill_spS_xTNF_Products( _
         currentNode.Nodes _
       , MyContextOfUse.Product _
       , True _
       , False _
       , New SqlGuid(CType(currentNode.Id, Guid)) _
       , SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductID.ColumnIndex _
       , -1 _
       , True _
       )
   ' currentNode.Nodes: this is the Nodes collection to fill
   ' MyContextOfUse.Product: this is the context of use of the nodes being added
   ' true: yes I want to purge the Nodes collection
   ' false: no I do not want to add a sub node to the added nodes
   ' (Guid)currentNode.Id: This is the value to use for the @CategoryID stored procedure parameter
   ' SPs.spS_xTNF_Products.Resultset1.Fields.Column_ProductID.ColumnIndex: this is the column index of the primary key
   ' -1: We do not want to use one specific column for the display but rather be called in the FormatdDisplay event to format this display
   ' true: I want to get track of all columns for each row
 End Select

 ' Let's specify that this node is UpToDate now
 currentNode.IsUpToDate = True

End Sub

Private Sub TreeView1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

 Dim currentNode As StoredProcedureCustomTreeNode
 Try
  currentNode = CType(e.Node, StoredProcedureCustomTreeNode)
 Catch

 End Try

 If currentNode Is Nothing Then Return

 Select Case CType(currentNode.ContextOfUse, MyContextOfUse)

  Case MyContextOfUse.Category
   Dim productsCount As SqlInt32 = CType(currentNode.Columns(SPs.spS_xTNF_Categories.Resultset1.Fields.Column_ProductsCount.ColumnIndex), SqlInt32)
   StatusBar1.Text = String.Format("This category has {0} products", productsCount.Value)

  Case MyContextOfUse.Product
   Dim supplierName As SqlString = CType(currentNode.Columns(SPs.spS_xTNF_Products.Resultset1.Fields.Column_SupplierName.ColumnIndex), SqlString)
   StatusBar1.Text = IIf(supplierName.IsNull, "No supplier", String.Format("Main supplier for this product is: {0}", supplierName.Value))

 End Select

End Sub

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 08 Jun 2004 14:13

I have posted a new build with some enhancements and bug fixes. A new enhancement is the transaction support that was added to the "Business Component Layer" Add-On (be sure to reimport the new version of this Add-On into your repository). Here is an example of code:


[Database]--------------------------------------------------------------------
CREATE DATABASE DemoBC (
 CREATE TABLE [Category] (
  [CategoryID]  uniqueidentifier -> ID
  [CategoryName] [varchar] (255), -> Name
 )

 CREATE TABLE [Product] (
  [ProductID]  uniqueidentifier, -> ID
  [ProductName] [varchar] (255), -> Name
  [ProductCategoryID] [uniqueidentifier], -> CategoryID
  CONSTRAINT [FK_Product_Category] FOREIGN KEY
  ([ProductCategoryID]) REFERENCES [Category] ([CategoryID])
 )
)

[C#.NET]--------------------------------------------------------------------
using System.Data.SqlTypes;
using System.Data.SqlClient;
using DemoBC.BusinessComponents;

// This method is going to be called from different contexts:
// ConnectionString, SqlConnection and SqlTransaction
private void DoSomeStuff(Categories categories) {

 foreach (Category myCategory in categories) {

  for (int index = 0; index < 10; index++) {

   Product newProduct = new Product();
   newProduct.Name = string.Format("Product {0}",  index);

   // You do not need to do this anymore: newProduct.CategoryID = myCategory.ID
   // It is done automatically from the category products collection
   newProduct = (Product)myCategory.Products.Add(newProduct);
  }

  foreach (Product myProduct in myCategory.Products.AddedRecords) {

   // Here is how we can browse the newly added records
   myProduct.Name = new SqlString(string.Format("{0} - Name was updated", myProduct.Name.Value));
   myProduct.Update();
  }
 }
}

// We use a connection string
private void button1_Click(object sender, System.EventArgs e) {

 string connectionString = "...";
 Categories myCategories = new Categories(connectionString);
 DoSomeStuff(myCategories);
}

// We use a SqlConnection
private void button2_Click(object sender, System.EventArgs e) {

 string connectionString = "...";
 SqlConnection sqlConnection = new SqlConnection(connectionString);
 sqlConnection.Open();

 Categories myCategories = new Categories(sqlConnection);
 DoSomeStuff(myCategories);

 // Warning, if you need to keep using the objects loaded by this
 // sqlConnection, you should NOT close the connection
 sqlConnection.Close();
}

// We use a SqlTransaction
private void button3_Click(object sender, System.EventArgs e) {

 string connectionString = "...";
 SqlConnection sqlConnection = new SqlConnection(connectionString);
 sqlConnection.Open();

 SqlTransaction sqlTransaction =
 sqlConnection.BeginTransaction("TransactionName");

 Categories myCategories = new Categories(sqlTransaction);
 DoSomeStuff(myCategories);

 sqlTransaction.Commit(); // or sqlTransaction.Rollback();

 // Warning, if you need to keep using the objects loaded by this
 // sqlConnection, you should NOT close the connection
 sqlConnection.Close();
}

[VB.NET]--------------------------------------------------------------------
Imports System.Data.SqlTypes
Imports System.Data.SqlClient
Imports DemoBC.BusinessComponents

' This method is going to be called from different contexts:
' ConnectionString, SqlConnection and SqlTransaction
Private Sub DoSomeStuff(ByVal categories As Categories)

 For Each myCategory As Category In categories

  For index As Integer = 0 To 9

   Dim newProduct As New Product()
   newProduct.Name = String.Format("Product {0}",  index)

   ' You do not need to do this anymore: newProduct.CategoryID = myCategory.ID
   ' It is done automatically from the category products collection
   newProduct = CType(myCategory.Products.Add(newProduct), Product)

  Next

  For Each myProduct As Product In myCategory.Products.AddedRecords

   ' Here is how we can browse the newly added records
   myProduct.Name = New SqlString(String.Format("{0} - Name was updated", myProduct.Name.Value))
   myProduct.Update()

  Next

 Next

End Sub

' We use a connetion string
Private Sub button1_Click(ByVal sender As Object , ByVal e As System.EventArgs) Handles Button1.Click

 Dim connectionString As String = "..."
 Dim myCategories As New Categories(connectionString)
 DoSomeStuff(myCategories)

End Sub

' We use SqlConnection
Private Sub button2_Click(ByVal sender As Object , ByVal e As System.EventArgs) Handles Button2.Click

 Dim connectionString As String = "..."
 Dim sqlConnection As New SqlConnection(connectionString)
 sqlConnection.Open()

 Dim myCategories As New Categories(sqlConnection)
 DoSomeStuff(myCategories)

 ' Warning, if you need to keep using the objects loaded by this
 ' sqlConnection, you should NOT close the connection

 sqlConnection.Close()

End Sub

' We use SqlTransaction
Private Sub button3_Click(ByVal sender As Object , ByVal e As System.EventArgs) Handles Button3.Click

 Dim connectionString As String = "..."
 Dim sqlConnection As New SqlConnection(connectionString)
 sqlConnection.Open()

 Dim sqlTransaction As SqlTransaction =
 sqlConnection.BeginTransaction("TransactionName")

 Dim myCategories = New Categories(sqlTransaction)
 DoSomeStuff(myCategories)

 sqlTransaction.Commit() ' or sqlTransaction.Rollback()

 ' Warning, if you need to keep using the objects loaded by this
 ' sqlConnection, you should NOT close the connection
 sqlConnection.Close()

End Sub

Author: "olymars"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 08 Apr 2004 02:24
Welcome to my blog! My name is Pascal Belaud and I'm a Developer Evangelist working at Microsoft France. I'm also the author of a SQL Server based code generator code-named: OlyMars...(read more)
Author: "olymars"
Comments Send by mail Print  Save  Delicious 
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader