EditGetting 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.
Edit1. 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 |
Edit2. 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.
Edit2.1: 01. Getting Started - Required Properties
At the bare minimum, you must fill out the first 3 properties as seen below:
 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 |
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 |
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 |
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.
Edit2.2: 02b. Filter by Individual Objects - Optional
Top
 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 |
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 |
Edit2.3: 02. Framework Generation - Optional
Top
 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 |
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.
Edit2.4: 03. Namespaces - Required
Top
 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
Edit2.5: 04. General - Advanced
Top
 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.
Edit2.6: 05. WebLibrary - Advanced
Top
 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.
Edit2.7: 06. Web - Advanced
Top
 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.
Edit2.8: 06b. Website - Advanced
Top
 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 |
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.
Edit2.10: 07. CRUD Advanced
Top
 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 |
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.
Edit2.11: 08. Stored Procedures - Advanced
Top
 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.
Edit2.12: 09. CodeStyle - Advanced
Top
 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
Edit3 .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.
Edit3.1: Reading the 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.
Edit3.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 |
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 |
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 |
Build Result:
You can monitor the build process through the output window, we've shown it here completed and more importantly successful.
 Build Results |
Edit4 .netTiers Configuration
Top
 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.
Edit5 Ready to Code
Top
 Intellisense |
Strongly Typed DataSource controls: You will find that just by typing
 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 |
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 |
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 |
 Edit |
Include Directives:
When you want to actually interact with the data, you simply have to include your the generated tiers as using directives.
1
using Northwind.Entities;
2
using Northwind.Services;
We recommend as much encapsulation as possible, with both your Service Objects and your Collection/Entity classes.
 Using in Codebehind |
How to Access Code:
Edit5.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
Edit5.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>));
Edit5.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
}