.netTiers
Help Wanted! If you are using .netTiers and find it as invaluable as we do, please consider giving back to the .netTiers team by helping with our effort to fully document .netTiers. To help, simply create an account and you will then be able to edit this wiki.

Getting Started

Modified: 08/16/2010 05:45 PM by mikiurban - Categorized as: Documentation
Edit

Getting Started



.netTiers are a set of templates written in C# and is built to work with the CodeSmith template code generation platform. CodeSmith itself uses a familiar ASP.NET syntax so .netTiers is not written in any obscure language or syntax that you couldn't sit down and understand what's going on in a very short time. The power of .netTiers is that it is a templatized approach to a common problem, and does not prohibit you from changing things or knowing what is going on under the covers.


Edit

1. Installing .netTiers

Once you have downloaded the .netTiers .zip file from the www.netTiers.com/download website, simply extract the files to your favorite projects directory. It's required that you have CodeSmith installed and registered by this point on your system. Here's a glimpse into what you'll see when you extract the directories. We'll delve more into the folder hierarchy later, but right now we're simply interested in doing our first generation.
Folder Structure

Folder Structure

Edit

2. Required Setup

To execute, you simply have to run (double-click) the main template, NetTiers.cst found in the root of the folder found where you extracted the templates. CodeSmith Explorer will begin, and you will see the .netTiers Property Set.

Edit

2.1: 01. Getting Started - Required Properties



At the bare minimum, you must fill out the first 3 properties as seen below:
Required Properties

Required Properties


Choose Source Database: This property is the heart of the .netTiers meta data for generation. You should select the database that the tables views, and stored procedures should be based on for generation.

IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated.

Choose a DataSource

Choose a DataSource



If you don't see your datasource, you will have to create one of your own, click Add and fill the Datasource Fields: Name, Provider Type, and ConnectionString.

Creating a Data Source

Creating a Data Source




Now that you've created your own entry, you can select it for generation. Setting this property will also try to default the the values of the OutputDirectory and your RootNameSpace by appending the datasource name to them.

Database Picker

Database Picker


In the image above, Northwind was selected as our datasource, and the output directory became "C:\NetTiers\Northwind" and Northwind also became the RootNamespace.

OutputDirectory: The root windows directory to output the generated project to. It is usually best that this be a new directory unless you've worked with the templates for awhile.

RootNameSpace: Root namespace for generated projects and C# classes. This will be the prefix for the other project namespaces. Example: If you enter NetTiers.Northwind here, and you enter Entities in BLLNamespace, then you will see NetTiers.Northwind.Entities for your Entity Layer.

Note: This is all that is required to generate a successful Data Access Layer from the .netTiers templates. There are many more options and other layers you can generate, you can skip down to #4, Configuration if you don't want to see the added generation options.

Edit

2.2: 02b. Filter by Individual Objects - Optional

Top

Default Values

Default Values


EnumTables: The tables to generate as enums. Your columns must meet the following rules.

1. The first column must be a primary key (which will become the Enum value), 2. The second column must be a string with a unique column constraint index (which becomes the Enum Name). The optional third column will be the description of the generated enum. 3. You must also select this table in the SourceTable as well in order to generate the enum.

Source Tables

Source Tables


SourceTables: The tables you wish to generate into entities, if you do not select any SourceTables or SourceViews, and SourceDatabase is completed, then the entire database will be generated.

SourceViews: The views you wish to generate into entities, if you do not select any SourceTables or SourceViews, and SourceDatabase is completed, then the entire database will be generated.

Filled Values

Filled Values



Edit

2.3: 02. Framework Generation - Optional

Top

Default Values

Default Values

CustomCodeFolderName: If specified, indicates the name of a folder that can contains custom classes to dynamically add to each project. This is useful if you plan on adding customized code aside from using the concrete classes or helper methods to any of the generated projects.

ExecuteSql: If true the stored procedures are attempted to be installed on the sql server for you. (The SQL file is still generated and placed in the Namespace.SQL directory).

IncludeComponentLayer: The pattern type to implement in the Component Layer. The component layer is considered to be where you place core business rule implementations and in new implementations should be the entry point into your domain logic. You can choose either Service Layer (like the Manager pattern), or Domain Model.

NOTE: The Service Layer is by far the most flexible and offers advanced features throughout the framework, like a ServiceLayer workflow pipeline and a workspace. The DomainModel should be used on basic applications and prototypes not requiring advanced workflow and loose coupling logic.

IncludeDatabaseFeatures: Indicates which database specific features to generate. The default is SQL 2000 compatibility, but you can select optionally choose Sql2005, which will generate optimized paging procedures specifically for SQL Server 2005.

Shown Filled

Shown Filled


IncludeUnitTest: Indicates type of Unit tests to be generated. The options are:

None: No unit test should be included. NUnit: NUnit tests should be generated. VSTS: Visual Studio Team System tests should be included.

IncludeWCFDataAttributes: Indicates if the WCF Attributes, DataContract and DataMember, should be included on the entity classes. Requires the latest Windows Communication Framework installed on your machine.

IncludeXmlAttributes: Indicates if the Xml attributes, XmlElement(IsNullable=true), should be included on all of the entity classes.

LaunchVisualStudio: Attempts to launch Visual Studio with the generated solution only if there are no instances already open.

SQLFolderName: The sub-folder to output the SQL scripts. This name is appended to the RootNameSpace, so if you enter SQL the folder will be RootNameSpace.SQL

ViewReport: Indicates if the HTML generation report should be shown at the end of the report.

Edit

2.4: 03. Namespaces - Required

Top

Default Values

Default Values



BusinessLogicLayerNameSpace: The sub-namespace that is added to the root namespace for the Entity Layer. So if RootNameSpace = "Northwind", and this property is "Entities" the resultant namespace for the entities would Northwind.Entities

ComponentLayerNameSpace: The sub-namespace for the given business layer you choose in the IncludeComponentLayer property. So if RootNameSpace = "Northwind", and this property is "Services" the resultant namespace for the services would Northwind.Services

DataAccessLayerNameSpace: The sub-namespace that is added to the root namespace for the Base Data Access Layer. So if RootNameSpace = "Northwind", and this property is "Data" the resultant namespace for the base data access layer would Northwind.Data

UnitTestsNameSpace: The sub-namespace that is added to the root namespace for the UnitTest Layer. So if RootNameSpace = "Northwind", the resultant namespace for the unit test swould Northwind.UnitTests

Edit

2.5: 04. General - Advanced

Top

Shown Filled

Shown Filled


CompanyName: The name of your company, or client's company. This is only for documenation and any references to the company.

CompanyURL: The URL of your company, or client's company. This is only for documenation and any references to the company.

SignAssembly: If true, the generated projects, when building, will try to sign the assemblies and search for {generated netTiers solution file name}.snk in the local root directory(OutputDirectory). This strong names your assemblies and is useful for advanced .net options and security.

  • Note that this will require you obtain strong name versions of the Enterprise Library assemblies required by netTiers. The best way to do this is to sign the Enterprise Library assemblies yourself with your own key file.

Edit

2.6: 05. WebLibrary - Advanced

Top

Default Values

Default Values

GenerateWebLibrary: Indicates if the web library should be generated. This contains the EntityDataSource, Specialized Typed DataSource controls of your domain and other extremely helpful Asp.Net utility classes.

IncludeDesignTimeSupport: Indicates if Visual Studio design-time support should be provided for the Web Library Typed DataSource controls. Edit

2.7: 06. Web - Advanced

Top

Default Values

Default Values


GenerateWebAdmin: Indicates if the web admin user controls should be generated. These are CRUD control admin screens that you can use to help manage

GenerateWebService: Indicates if the Webservice DataAccess Provider should be generated. If you are in a situation where you need to create an EndPoint of your Data API, then include this option. WebAdminOutputPath: The full path for generated WebAdmin UserControl files.

WebServiceOutputPath: The full path for the the WebService files. This path must match with the WebserviceURL in IIS.

WebServiceURL: The base URL for the webservice specified above in WebServiceOutputPath, eg: http://localhost/NetTiersServices.

Edit

2.8: 06b. Website - Advanced

Top

Default Values

Default Values

GenerateWebsite: Indicates if a complete website should be generated. This is useful for new webform projects and you need to get up and going immediately. A full website along with all necessary references will already be included and ready to start working with your data.

IncludeAtlasLibrary: Indicates whether to include a reference to the Microsoft AJAX (used to be known as "Atlas") Component Library in the website generated. This is useful if you want to immediately take advantage of the Microsoft AJAX Framework in your WebForms.

IncludeAtlasToolkit: Indicates whether to include a reference to the AJAX Control Toolkit. This property is only taken into account when IncludeAtlasLibrary is true. The Microsoft AJAX Toolkit is a set of advanced controls that take full advantage of ajax and javascript behaviors.

Shown Filled

Shown Filled

OverwriteWebConfig: Indicates if the Web.config should be overwritten in the GenerateWebsite generated website project. This is useful if you've customized your web.config and don't want to overwrite those settings.

UseWebAppProject: Indicates if a Web Application Project file should be generated. Note: you must have the Visual Studio Maintenance Patch and the WebApplication Projects Visual Studio Extension installed in order to use this feature. This creates a project file for website project much like Visual Studio 2003.

Edit

2.10: 07. CRUD Advanced

Top

Default Values

Default Values


CustomNonMatchingReturnType: When using custom stored procedures, if the returned rows do not match the fields in an entity, a DataSet or IDataReader will be returned. Choose One. This is useful if you've returned more than one resultset in a custom procedure; you can use a ConvertToDataSet(IDataReader) method in the Utility class to convert that to a DataSet.

CustomProcedureStartsWith: include custom stored procedures, this is the pattern that NetTiers will look for your custom stored procedures to start with. A string format will be used to match the beginning of the procedure pattern. So, {0}=TableName, {1}=ProcedurePrefix(See Property Below). By default NetTiers will look at tables that starts with '_{0}_', which means it will detect the procedure _TableName_GetByBirthdate and generate the necessary plumbing to wrap your custom stored procedure. Your new method can be accessed by DataRepository.TableNameProvider.GetByBirthdate();

IncludeCustoms: Indicates if you would like .netTiers to attempt to generate wrappers into the API for your custom stored procedures.

IncludeDelete: If true delete procedures will be generated into the API.

IncludeDrop: If true drop comands along with all of the stored procedures will be generated.

IncludeFind: If true Find procedures will be generated into the API.

IncludeGet: If true Get procedures will be generated into the API.

IncludeGetList: If true GetList procedures will be generated into the API.

IncludeGetListByFK: If true GetList By Foreign Key procedures will be generated into the API. So if your Order Table has a CustomerId column in it, and its a foreign key back to your Customers Table. Then a method called GetByCustomerId(int customerId) will be created.

IncludeGetListByIX: If true GetList By Index procedures will be generated into the API. So if your Order Table has a Status column in it, and its an index on your Orders Table. Then a method called GetByStatus(string status) will be created.

Shown Filled

Shown Filled


IncludeInsert: If true Insert procedures will be generated into the API.

IncludeManyToMany: If true .netTiers will attempt to gain insight into your many to many relationships and generate procedures into the API.

IncludeRelations: If true .netTiers will use the your database meta data to discover relationships and will generate into the API.

IncludeSave: If true save methods will be generated into the API that wrap Insert/Update/Delete.

IncludeUpdate: If true update procedures will be generated into the API.

IsolationLevel: Isolation level to use for the generated procedures.

RetryEnabled: Enabling Retry will add code retry the queries that failed with data exceptions. Useful to if your database becomes temporarily unavailable. Use with caution in that if a transaction fails in the database, then the retry can not continue because the transaction is now in a failed state.

RetryMaxAttempts: The number of attempts that will be made.

RetrySleepStyle:
  • Constant - Each sleep will be the n milliseconds.
  • Linear - Each sleep will increase by n*attempts milliseconds.
  • Exponential - Each sleep will increase exponential by n^attempts milliseconds.

RetrySleepTime: The number of milliseconds that the current thread will sleep between attempts. Sleep only occurs if an exception is thrown.

Edit

2.11: 08. Stored Procedures - Advanced

Top

Default Values

Default Values


DeleteSuffix: Suffix to use for all generated DELETE stored procedures.

FindSuffix: Suffix to use for all generated selective FIND stored procedures.

GrantReadUser: Optional user or role to GRANT EXEC Procedure permissions to (for all generated read-only procedures)

GrantUser: Optional user or role to GRANT EXEC Procedure permissions to (for all generated procedures)

ProcedurePrefix: The prefix to attach to the stored procedure names, ex: "usp_" will give you "usp_Orders_GetList"

SelectAllSuffix: Suffix to use for all generated selective SELECT stored procedures.

UpdateSuffix: Suffix to use for all generated selective Update stored procedures.

Edit

2.12: 09. CodeStyle - Advanced

Top

Shown Filled

Shown Filled



AliasFilePath: Optional File Path to a table/object alias file. If you have a table name called "Customers" and you wanted it to be "Customer" then you would create a "Customer" table. Create a NewLine Delimited list of the table names and their Aliases, seperated by a colon. This is also useful if you encounter a naming collision with a type that's already included in the .Net Framework. For example if you have a table named Environment, then you will get a naming conflict with the .Net Type Environment.

Alias.txt
  • Customers:Customer
  • Orders:Order

BaseClassFormat: The format for any base class name. Parameter {0} is replaced by the original class name.

ChangeUnderscoreToPascalCase: If set to true, attempts to treat underscores '_' and dashes '-' as word separators for Pascal casing. For example, a table named "aspnet_users" will get converted to "AspnetUsers".

CollectionFormat: The format for any collection class name. Parameter {0} is replaced by the collection item class name.

ColumnClassNameFormat: The format used by the Column ClassNameFormat. Parameter {0} is replaced by the original class name.

ComparerClassNameFormat: The format used by the Comparer ClassNameFormat. Parameter {0} is replaced by the original class name.

EntityFormat: The format for entity class name. Parameter {0} is replaced by the trimmed table name, in Pascal case.

EntityKeyFormat: The format for the entity key class names. Parameter {0} is replaced by the trimmed table name, in Pascal case.

EnumFormat: The format for any Enum. Parameter {0} is replaced by the original class name.

EventArgsClassNameFormat: The format used by the EventArgs ClassNameFormat. Parameter {0} is replaced by the original class name.

EventHandlerClassNameFormat: The format used by the EventHandler ClassNameFormat. Parameter {0} is replaced by the original class name.

GenericListFormat: The format for the tables generic class name. Parameter {0} is replaced by the name of the class that will be stored in the list.

GenericViewFormat: The format for the views generic class name. Parameter {0} is replaced by the name of the class that will be stored in the list. InterfaceFormat: The format for any interface name. Parameter {0} is replaced by the original interface name based on the class name.

InterfaceFormat: The format for the Interface names. Parameter {0} is replaced by the secondary class name

ManyToManyFormat: The format for many to many methods. Parameter {0} is replaced by the secondary class name

MethodNames: The names to use for various generated methods.
  • BulkInsert: The name of the method used to perform a BulkInsert operation.
  • DeepLoad: The name of the method used to perform a DeepLoad operation.
  • DeepSave: The name of the method used to perform a DeepSave operation.
  • Delete: The name of the method used to perform a Delete operation.
  • Find: The name of the method used to perform a Find operation.
  • Get: The name of the method used to perform a Get operation.
  • GetAll: The name of the method used to perform a GetAll operation.
  • GetPaged: The name of the method used to perform a GetPaged operation.
  • GetTotalItems: The name of the method used to perform a GetTotalItems operation.
  • Insert: The name of the method used to perform an Insert operation.
  • Save: The name of the method used to perform a Save operation.
  • Update: The name of the method used to perform a Update operation.

ProviderFormat: The format for any provider class name. Parameter {0} is replaced by the original class name

SafeNamePrefix: Used to prefix names that would be unsafe (invalid) in C#. I.e. C# keywords, any characters except letters, digits (Not first char, though), and '_'. Note: Although spaces are not valid in C# names, they will automatically be removed. Dashes are also invalid, but can be supressed using the 'ChangeUnderscoreToPascalCase' option.

ServiceClassNameFormat: The format for the Service Class names. Parameter {0} is replaced by the related entity's class name.

StrippedTablePrefixes: The table prefixes to strip from the classes name, delimited by comma.

StrippedTableSuffixes: The table suffixes to strip from the class name, delimited by semi-colon and case sensitive.

UsePascalCasing: Used to determine the type of pascal casing used. None - no casing is done, Style1 - original casing which does not convert uppercase characters, Style2 - newer casing that does convert uppercase

Edit

3 .netTiers Generation

Top Generate: Save Property Set: The first thing you want to do is save your property set, which is noted by the Arrow and turquoise highlight. This enables you to quickly reload your property without having to re-configure your property set.

Expand Window: Second, click the arrows depicted by the green area to expand the window so you can see the Template Output. This will let you see any error messages, if any.

Generate: Third, click the generate button and wait approximately 30 seconds to 2 minutes depending on this size of the database. Depending on whether or not you chose to view the Generation Report, once .netTiers is completed, your default browser will pop-up showing the generation report.

Edit

3.1: Reading the Generation Report



Generation Report

Generation Report

Summary: The summary section of the report gives you an overall synopsis of total objects or errors that occured during the generation process. Configuration: The .netTiers Quick Configuration is a section that enables you to quickly configure your winforms or web application. Essentially it requires you to add a section to your configuration section to your web/app config of the NetTiersServiceSection. This allows .netTiers to read critical information during runtime.

Documentation: The documentation section has a link back to the official .netTiers documentation. Which will most likely be this file. It also contains a very useful quick start of sample API calls, which is meant to get you used to how you make calls into your customized API. Details - Generated Classes: This is a "rather long" list of all your generated objects. This is useful if you added a new table to your generation process, but you don't see the objects for them, you can check here and verify if the table actually got created.

Edit

3.2: Verifying Complete Generation

Top

Browse to OutputDirectory: Using Windows Explorer, browse to the OutputDirectory that you chose earlier in the setup process. You will see a solution file, along with several directories. Each directory represents usually Tier in generated code. Let's make sure your generation process was completely successful before you import this into an existing solution if you already have one.

Folder Structure

Folder Structure


Open Solution: Double click this solution file. You can later attach any new project to this solution. However, even if you're starting from scratch we recommend making a new solution, that is yours and simply importing this solution into your solution. This will allow you to change things up as much as you want in a flexible manner and still not have to worry about ruining anything. Things like SCC can potentially change the way you work with the templates, so careful seperation will allow you to be happy with the results. This new solution can be a Master Solution of sorts that can contains a web/winforms app, and includes the NetTiers projects. You would also have our Generated solution, which is nice and lean for your quick entity and data layer modifications.

Project Organization

Project Organization


Compile Solution: Now that you're solution is open, the first thing we want to do is build all the libraries to ensure that .netTiers generated valid c# code. If you've configured your solution as I have, that's 7 projects thatwere

How's that for a Time Saver!

Compile Your Generated Code

Compile Your Generated Code



Build Result: You can monitor the build process through the output window, we've shown it here completed and more importantly successful.

Build Results

Build Results




Edit

4 .netTiers Configuration

Top
Configuration

Configuration


Open Web/App.config: Opening the web/app configuration. If you've chosen to have .netTiers generate a web application project for you, then you should already have a configuration that is property configured. You can choose to skip over this step. Otherwise, if you're working on an existing project or a winforms application, then follow along. The configuration depicted has the configuration along with the Enterprise Library and Atlas configuration.

The configSection that you need to be concerned with is:

1<section name="Northwind.Data" 2 type="Northwind.Data.Bases.NetTiersServiceSection, Northwind.Data" allowDefinition="MachineToApplication" 3 restartOnExternalChanges="true" />


Remember, the Connection String name corresponds to the Asp.Net ConnectionString config section you are using. The Northwind.Data Section of the configuration is the critical data that .netTiers needs to know in order to run successfully at runtime.

Name: This is the name of your provider. You will be able to access this provider by name if you don't configure it as the default provider.

Type: This is the Fully qualified Type string of this configured provider.

ConnectionStringName: The first thing you want to do is save your property set, which is noted by the Arrow and turquoise highlight. This enables you to quickly reload your property without having to re-configure your property set.

EntityFactoryType: The entity factory type provides an entity creational factory that dynamically finds where your entity is located and creates a version of that entity. hooks for user interaction during the creational process of the entity. It allows you to maybe subscribe to event if you needed to or have something process the entity prior to setting the data from the data reader. This is also useful in case you've selected the DomainModel, in which case, you want to create Domain objects, but they are not visible to the Data Layer, so you would have to "discover" these types. Ex:Northwind.Entities.EntityFactory

UseEntityFactory: Indicating if you want to use the EntityFactory for creation of the entities. This is required to be true, if youv'e selected the domain model.

EnableEntityTracking: This allows you to have a performant entity cache using Enterprise Library's ObjectBuilder, Locator class in your application using weak references so that if there no references to the entity, it will be garbage collected.

EnableMethodAuthorization: If using one of the two component layer projects, this will enable runtime code authorization utilizing Microsoft Asp.net's Role Provider and Microsoft Enterprise Library Authorization Provider. You might want to leave this as false until you can get a grasp of the framework, and have time to configure the required rules for using Method Authorization.

UseStoredProcedure: If you chose not to execute all of those procs onto the server, there is a file called procedures.xml that essentially is an xml?ed version of the procedures. Setting useStoredProcedure to false, causes NetTiers to simply use parameterized SQL instead of the crud procs. This is useful if you would like to organize your stored procedures.

Edit

5 Ready to Code

Top

Intellisense

Intellisense


Strongly Typed DataSource controls: You will find that just by typing
Intellisense

Intellisense


When you select the SelectMethod Attribute, you will see via intellisense a list of all available methods from your domain. How cool is that!

Web Form

Web Form


Here's an example of a webform in it's minimilist form, that would display a grid of all Employees with Auto-Generated columns.

Design View

Design View


Taking the form and selecting only the columns that I want, we create a nice grid.

Here's the result of of the form. The wonderful part of the Typed DataSource control is that you don't have to do anything when you want to edit/insert/delete an object. You simply have the grid call the Edit/Delete/Insert command, which can be done a variety of ways in ASP.net 2.0.

Results

Results


Edit

Edit



Include Directives: When you want to actually interact with the data, you simply have to include your the generated tiers as using directives.

1using Northwind.Entities; 2using Northwind.Services;


We recommend as much encapsulation as possible, with both your Service Objects and your Collection/Entity classes.

Using in Codebehind

Using in Codebehind



How to Access Code:

Edit

5.1: Quick Start Sample API

Top

1 AccountService accountsService = new AccountsService(); 2 3 //GetAll() 4 TList<Accounts> accountList = accountsService.GetAll(); 5 6 //GetPagedl() 7 TList<Accounts> accountList = 8 accountsService.GetPaged("IsActive = 1 AND AccountName LIKE 'smi%'"); 9 10 //GetByFk() 11 TList<Accounts> accountList = accountsService.GetByCustomerId(25); 12 13 //GetIX() 14 TList<Accounts> accountList = accountsService.GetByAccountCreatedDate(new DateTime("1/1/2006")); 15 16 17 18 //Get() 19 entity.Entitykey; 20 TList<Accounts> accountList = accountsService.Get(entity.EntityKey); 21 22 Account accountEntity = new Account(); 23 accountEntity.AccountName = "MyAccountName"; 24 accountEntity.CreatedDate = DateTime.Now; 25 26 //Insert() 27 TList<Accounts> accountList = accountsService.Insert(accountEntity); 28 29 //Delete() 30 TList<Accounts> accountList = accountsService.Delete(accountEntity); 31 32 //Delete() 33 TList<Accounts> accountList = accountsService.Delete(23); 34 35 //Update() 36 accountEntity.AccountName = "MyAccountName 2"; 37 TList<Accounts> accountList = accountsService.Update(accountEntity); 38 39 //GetByManyToManyl() 40 TList<Customers> accountList = accountsService.GetCustomers_From_AccountsReceivable(); 41 42 //GetCustomProcedureName() 43 TList<Accounts> accountList = accountsService.GetByAccountMaturationDate(); 44 45 //DeepLoadByIdl() using PK 46 Account account = accountsService.DeepLoadByAccountId( 47 id, 48 false, 49 DeepLoadType.IncludeChildren, 50 typeof(Customers), 51 typeof(TList<ChartOfAccounts>)); 52 53 54 //DeepLoadByIdl() using FK 55 TList<Account> account = accountsService.DeepLoadByCustomerId( 56 id, 57 false, 58 DeepLoadType.IncludeChildren, 59 typeof(Customers), 60 typeof(TList<ChartOfAccounts>)); 61 62 63 //already instatiated objects 64 //DeepLoad 65 accountsService.DeepLoad( 66 myAccountEntity, 67 false, 68 DeepLoadType.IncludeChildren, 69 typeof(Customers), 70 typeof(TList<ChartOfAccounts>)); 71 72 73 //DeepSave 74 accountsService.DeepSave( 75 myAccountEntity, 76 false, 77 DeepSaveType.IncludeChildren, 78 typeof(Customers), 79 typeof(TList<ChartOfAccounts>)); 80


Edit

5.2: Working with the Code

Top

You will quickly discover that while there is a slew code being generated, the concepts themselves are simple, and familiar concepts based on proven practices and patterns.

1 string custId = "TRAIH"; 2 3 //I get a single instance of the customer I want. 4 5 Customers customer = DataRepository.CustomersProvider.GetByCustomerID(custId); 6 7 8 Type[] typesToDeepLoad = 9 new Type[] { typeof(TList<Orders>), typeof(TList<Products>) }; 10 11 12 //go further than one level down object graph 13 bool goMoreThanOneLevelDeep = true; 14 15 16 /// I'm going to deep load this customer, but I only want 17 /// to see his orders and the products that he's made, 18 /// I really don't care about the line items 19 /// But the neat thing is that the relationship to products is through 20 /// line items. 21 /// the object graph looks somethign like this 22 /// - Customer 23 /// --> 24 /// ---OrderDetails 25 /// ---ProductCollection 26 /// --CustomerDemographics 27 /// --CustomerDemographicsCollection_From_CustomerCustomerDemo 28 DataRepository.CustomersProvider.DeepLoad( 29 customer, // my customer 30 goMoreThanOneLevelDeep, //go further than one level down object graph 31 DeepLoadType.IncludeChildren, //be Inclusive Descriminator 32 typesToDeepLoad); 33 34 35 /// Call could be condensed like 36 DataRepository.CustomersProvider.DeepLoad(customer, true, DeepLoadType.IncludeChildren, typeof(TList<Orders>), typeof(TList<Products>));


Edit

5.3: Working with the Entities

Top Using Collections in .netTiers, TList & VList: .netTiers has two generic lists that it exclusively uses for your entities. TList and VList. The TList is the most full featured and only works with Types that implement IEntity, which are entities that are generated from a table as formerly stated. VList is a list for limited View Entities that don't maintain EntityState.

1 Orders order = new Orders(); 2 order.OrderDate = new DateTime(2001, 8, 29); 3 order.ShipAddress = "302 West Main Street"; 4 order.ShipCity = "Atlantis"; 5 order.ShipCountry = "Anywhere"; 6 order.ShipName = "Frank Sanders"; 7 order.ShipPostalCode = "55512"; 8 order.ShipRegion = "Under the Sea"; 9 10 11 12 ///Index Of, Get's the location of the order in the list 13 int index = ordersList.IndexOf(order); 14 15 16 17 ///FindIndex 18 ///Returns the integer value if 19 ///one of the criteria matches your predicate 20 ordersList.FindIndex( 21 delegate(Orders orders) 22 { 23 return orders.RequiredDate < DateTime.Today.AddDays(2); 24 }); 25 26 27 28 ///Insert 29 ///Useful if you want to insert an order in a specific location 30 if (index < 0) 31 ordersList.Insert(0, order); 32 33 34 ///Add 35 ///Appends an order to the list 36 ordersList.Add(order); 37 38 39 ///AddNew 40 ///Appends a new order to the list 41 ordersList.AddNew(); 42 ordersList[ordersList.Count - 1].OrderDate = DateTime.Today; 43 44 45 ///RemoveEntity 46 ///Removes the order from the list and places it in DeletedItems 47 ordersList.RemoveEntity(order); 48 49 50 ///RemoveAt 51 ///Removes the first entry of the list 52 ordersList.RemoveAt(0); 53 54 55 ///RemoveAt 56 ///Removes the entity where it exists 57 ordersList.Remove(order); 58 59 60 ///ListChanged 61 ///Fires an event when the list has changed 62 ordersList.ListChanged += new System.ComponentModel.ListChangedEventHandler(ordersList_ListChanged); 63 64 65 ///IsDeletedCount 66 ///Returns the count of the DeletedItems Collection 67 int deletedCount = ordersList.IsDeletedCount; 68 Debug.Assert(deletedCount == ordersList.DeletedItems.Count); 69 70 71 ///IsDirtyCount 72 ///Returns the count of the items that have an 73 ///EntityState == EntityState.Changed 74 int dirtyCount = ordersList.IsDirtyCount; 75 Response.Write(string.Format("You have modified {0} entities.",dirtyCount)); 76 77 78 ///IsNewCount 79 ///Returns the count of the items that have an 80 ///EntityState == EntityState.Added 81 int newCount = ordersList.IsNewCount; 82 Response.Write(string.Format("You have added {0} entities.", newCount)); 83 84 85 ///FindAllBy 86 ///Returns a new List of Entities that 87 /// match the FindAllByType 88 ///FindAllByType.Contains, FindAllBy.StartsWith, FindAllByType.EndsWith 89 TList<Orders> sList = ordersList.FindAllBy(TList<Orders>.FindAllByType.StartsWith, OrdersColumn.ShipCity, "Atl"); 90 91 TList<Orders> cList = ordersList.FindAllBy(TList<Orders>.FindAllByType.Contains, OrdersColumn.ShipCity, "ant"); 92 93 TList<Orders> eList = ordersList.FindAllBy(TList<Orders>.FindAllByType.EndsWith, OrdersColumn.ShipCity, "tis"); 94 95 96 ///FindAll 97 ///Returns a new List of Entities that match using the Table Enum Columns 98 TList<Orders> eqList = ordersList.FindAll(OrdersColumn.ShipCity, "Atlantis"); 99 100 101 102 ///FindAll 103 ///Returns a new List of Entities using a predicate 104 TList<Orders> eqList2 = ordersList.FindAll( 105 delegate(Orders o2){ 106 return 107 o2.OrderDetailsCollection.Count > 0 && 108 o2.OrderDate == DateTime.Today; 109 }); 110 111 112 ///Exists 113 ///Returns a bool if one of the criteria matches your predicate 114 if (ordersList.Exists( 115 delegate(Orders o3) 116 { 117 return 118 o3.OrderDetailsCollection.Count > 0 && 119 o3.OrderDate == DateTime.Today; 120 })) 121 { 122 Response.Write("There are orders today"); 123 } 124 125 126 ///ToArray 127 ///Creates an orders array from a list 128 Orders[] orderArray = ordersList.ToArray(); 129 130 131 ///ToDataSet 132 ///Creates a DataSet with children relationships from your TList. 133 DataSet ds = ordersList.ToDataSet(true); 134 135 136 /// Filter as a string 137 /// Creates a view inside of your list using a case sensitive filter 138 /// Great for cached items that you need to show 139 /// different sets of entities based on criteria. 140 ordersList.Filter = "ShipCity = 'Atlantis'"; 141 ordersList.ApplyFilter(); 142 ordersList.ForEach( 143 delegate(Orders filteredOrder) 144 { 145 Debug.Assert(filteredOrder.ShipCity == "Atlantis"); 146 }); 147 148 149 ///To Remove the filter, you simply call RemoveFilter; 150 ordersList.RemoveFilter(); 151 152 /// Filter using a Predicate delegate 153 /// Great for needing to filter on items that 154 /// different sets of entities based on criteria. 155 ordersList.ApplyFilter(GetValidAtlantisOrders); 156 157 158 ordersList.ForEach(delegate(Orders filteredOrder) 159 { 160 Debug.Assert(filteredOrder.IsValid 161 && filteredOrder.ShipCity == "Atlantis"); 162 163 }); 164 165 166}//End Page_Load 167 168 169 170 /// <summary> 171 /// Gets the valid atlantis orders. 172 /// </summary> 173 /// <param name="o">The o.</param> 174 /// <returns></returns> 175 public bool GetValidAtlantisOrders(Orders o) 176 { 177 return (o.IsValid 178 && o.ShipCity == "Atlantis" 179 && o.OrderDetailsCollection.Count > 0 180 && o.OrderDetailsCollection.IsValid); 181 } 182 183 184 void ordersList_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) 185 { 186 throw new Exception("The method or operation is not implemented."); 187 }


ScrewTurn Wiki version 2.0.31.