Entity Layer

Table of Contents [Hide / Show]


Entity Layer
   What 
is  an Entity ?
      A bit of history: The Entity Relationship Model
      What
' s your definition of an entity?
      EntityBase
      What 
is  Entity State ?  
   Entity LifeCycle
      Base State Behavior
      Interface Implementations 
      What about generated views
?  Are they entities ?
   Entity Validation Rule Engine
      Example of Auto
- Generated Rules
      That
' s great, but, how do I add my own rules?
      So, how  do  I validate and see the error message ?
   Using Collections 
in  .netTiers, TList  &  VList:
   Entity Management Framework:
      EntityFactoryBase
      EntityCache
      IEntityCacheItem
      EntityLocator
      EntityManager




Edit 
Entity Layer


Edit 
What 
is  an Entity ?
An Entity 
is  not a regular .net type, it  is  a significant type that holds an intrinsic meaning that  is  essential  in  your application. Entities can be real or conceptual and  in  business applications, which .netTiers  is  tailored to, holds a special meaning to the data. For example: an Employee, an Order and OrderDetail are all entities. Entities are malleable and have a lifecycle, and their types must take extra special checks and balances to ensure the integrity of the entity. 

Edit 
A bit of history: The Entity Relationship Model
The entity first came to be known 
as  the Entity Relation model, ERM. You can read the white paper that pretty much coined the term Entity and the entity life cycle. The Entity Relationship Model  -  Toward A Unified View of Data  -  By Dr. Peter Chen. This  is  significant because it was the first time there was a segregration  in  the way we made representations  in  a program from our data. These representations allow to focus on creating a rich programmer experience with these valuable representations that we 

Edit 
What
' s your definition of an entity?
.netTiers uses the notion of the entity along with the TableModule  &  Data Transfer Object (DTO) Patterns  in  order to expose your database  as  entities. Meaning,  for  every table  in  your database, an entity will be generated  for  that table. The DTO allows you to pass the lightweight entities through the many tiers  while  still maintaining the loosely coupled open ended architecture of the Entity Layer, since it doesn ' t depend on any DataProvider. 

.netTiers will also attempt to discover all of the relationships that your table has with other tables 
in  the database and will create child properties of those relationships. This will build  out  your entire entity domain. Currently the relationship types supported are one to one, one to many, and and many to many relationships. These relationships make it easy  for  you to intuitively work with your entities and now have a logical  object  graph. There are several ways to create a certain relationship, but we ' ll discuss the rules in the Database Model section.

Example: Customer Entity 
///An example object graph of a customer entity looks like this.
/// Customer Parent
///   Order 1:1
///    OrderDetails //1:M
///    ProductCollection //1:M
///   CustomerDemographics //1:M
///   CustomerDemographicsCollection_From_CustomerCustomerDemo //M:M


Edit 
EntityBase
The entities all inherit from two parent classes, the user 
class  called EntityBase.cs which inherits from EntityBaseCore.generated.cs, the generated  class . As mentioned earlier, every .generated  class  will be generated over and over again,  do  not modify these classes  as  your work will be lost when you regenerate your code. 

These 
base  classes implement the the  base  behavior across all entities. The EntityBase  class  provides you with exlusive access to modify the behavior across all entities. You can  override  our  default  implementation and these changes will not  get  overwritten. This  is  a way  for  you to make changes and extend the behavior  while  at the same time, safeguarding your work. EntityBase The EntityBase classes provide behavior to manage state  using  the EntityState property. 



Edit 
What 
is  Entity State ?  
Entity State provides a way to track the current status of an entity 
in  it ' s entity lifecycle, which differs from the CLR object lifecycle. There are 4 main EntityStates, found in the EntityState enumeration, Unchanged, Added, Changed, and Deleted. You do not have to manually keep track of state, when you modify a property, or create a new entity, or read an entity from the database .netTiers will automatically change the state and keep track for you.



 
1   /**/ /// <summary>
  2   /// List of possible state for an entity.
  3   /// </summary>
  4   public   enum  EntityState
 
5  ... {
 
6     /**//// <summary>
 7     /// Entity is read in from the database, unchanged
 8     /// </summary>
 9     Unchanged=0
10
11     /**//// <summary>
12     /// Entity is new and not yet in the database
13     /// </summary>
14     Added=1
15
16     /**//// <summary>
17     /// Entity has been modified
18     /// </summary>
19     Changed=2
20
21     /**//// <summary>
22     /// Entity has been deleted
23     /// </summary>
24     Deleted=3
25 }




Edit 
Entity LifeCycle
Assuming you have no data 
in  your database, the very first thing you will  do   is  add data to the database. In order to  do   this , you will have to create a  new  entity. Let ' s use the Customer entity that we ' ve generated from the Northwind database, and create a  new  Customers entity and walk through the different states of the entity, which  as  mentioned earlier  is  different than the  object  lifecycle. 

 
1      /**/ ///STAGE 1: Added
  2      ///Create a new entity, whose EntityState is EntityState.Added               
  3     Customers customer  =   new  Customers();
 
4     customer.Address  =   " 102 West Main Street " ;
 
5     customer.City  =   " Atlantis " ;
 
6     customer.Region  =   " Sea " ;
 
7     customer.Phone  =   " 230-555-0909 " ;
 
8     Response.Write(customer.EntityState);  //  EntityState.Added;
  9  
10      /**/ ///Persist
11     DataRepository.CustomersProvider.Save(customer);
12
13
14      /**/ ///STAGE 2: Unchanged
15      /// The EntityState has been set to EntityState.Unchanged
16      ///Once we persist the entity, it will refresh the entity from the database
17      ///If there is an identity column in your table that the entity represents
18      /// then the new identity of the inserted value is returned as well.
19     Response.Write(customer.CustomerID);
20     Response.Write(customer.EntityState);  //  EntityState.Unchanged;
21
22  
23      /**/ ///STAGE 3: Changed
24      /// By modifying a property the entity will automatically 
25      /// change state to an EntityState.Changed state.
26     customer.Region  =   " Under The Sea " ;
27     Response.Write(customer.EntityState);  //  EntityState.Changed;
28     DataRepository.CustomersProvider.Save(customer);
29  
30
31      /**/ ///STAGE 4: Deleted
32      /// Two ways exist being in an EntityState.Deleted state for an Entity.
33      /// MarkToDelete() method, or directly calling Delete in the repository.
34      /// MarkToDelete() is mainly used when using the Save() method, 
35      /// wanting to delete an entity which aggregated 
36      /// and part of a Collection, a TList<Entity>.
37      /// If you are working with a single entity as depicted, you would  
38      /// just pass the entire entity into the DataRepository for Deletion.
39
40      ///Using Delete Method Directly on the Entity
41     DataRepository.CustomersProvider.Delete(customer);     
42
43      /**/ ///Using Save Method in DataRepository with MarkToDelete()
44     customer.MarkToDelete();
45     Response.Write(customer.EntityState);  //  EntityState.Deleted;
46     DataRepository.CustomersProvider.Save(customer);
47  
48      /**/ ///EntityState.Unchanged
49      ///Say I want to delete all customers that have a city = Atlantis
50      /// Whenever you get any entity items from the Database, once created 
51      /// the state is immediately changed to EntityState.Unchanged
52     TList < Customers >  myList  =  DataRepository.CustomersProvider.GetByCity( " Atlantis " );
53
54      for  ( int  i  =   0 ; i  <  myList.Count; i ++ )
55     ... {
56        Response.Write(myList[i].EntityState); // EntityState.Unchanged;
57        myList.RemoveEntity(myList[i]);
58
59        Response.Write(myList[i].EntityState); // EntityState.Deleted;
60    }

61
62       /**/ /// Now you've actually removed the entities from the list
63      Response.Write(myList.Count);  //  Prints 0
64  
65       /**/ /// They are however moved to a DeletedItems collection
66      Response.Write(myList.DeletedItems.Count);  // Prints 1
67
68       /**/ ///Will delete the items from the Database
69      DataRepository.CustomersProvider.Save(myList);
70
71       /**/ ///Or you can Iterate the list calling MarkToDelete();
72      myList.ForEach(
73          delegate (Customers c)
74             ... {
75                     c.MarkToDelete();
76            }

77         );
78
79  
80
81      /**/ ///Will persist all of the Deleted entities.
82     DataRepository.CustomersProvider.Save(myList);



Edit 
Base State Behavior
You can 
override  the  default  behavior  if  you wanted and managed how EntityState was used. Perhaps  if  you wanted to use a StateMachine instead to manage state. Overall, it ' s a flexible approach that should let you customize however you need to..

There are also some entity state descriptor properties such 
as  IsDeleted, IsDirty, IsNew. One other thing to note,  is  that you can remove the flag after  using  MarkToDelete by calling RemoveDeleteMark().

Excerpt from EntityBase.generated.cs

 
1          /**/ /// <summary>
  2          ///    True if object has been <see cref="MarkToDelete"/>. ReadOnly.
  3          /// </summary>
  4         [BrowsableAttribute( false ), XmlIgnoreAttribute()]
 
5          public   bool  IsDeleted
 
6         ... {
 
7            get ...return this.currentEntityState == EntityState.Deleted; }
 
8        }

 
9
10
11          /**/ /// <summary>
12          ///        Indicates if the object has been modified from its original state.
13          /// </summary>
14          /// <remarks>True if object has been modified; otherwise False;</remarks>
15         [BrowsableAttribute( false ), XmlIgnoreAttribute()]
16          public   bool  IsDirty
17         ... {
18            get
19            ...{
20                return this.currentEntityState != EntityState.Unchanged 
21                            && this.currentEntityState != EntityState.Added;
22            }

23        }

24
25          /**/ /// <summary>
26          ///        Indicates if the object is new.
27          /// </summary>
28          /// <remarks>True if objectis new; otherwise False;</remarks>
29         [BrowsableAttribute( false ), XmlIgnoreAttribute()]
30          public   bool  IsNew
31         ... {
32            get ...return this.currentEntityState == EntityState.Added; }
33            set ...this.currentEntityState = EntityState.Added; }
34        }

35
36
37          /**/ /// <summary>
38          ///        Indicates state of object
39          /// </summary>
40          /// <remarks>0=Unchanged, 1=Added, 2=Changed</remarks>
41         [BrowsableAttribute( false ), XmlIgnoreAttribute()]
42          public   virtual  EntityState EntityState
43         ... {
44            get ...return this.currentEntityState; }
45            set ...this.currentEntityState = value; }
46        }

47
48
49          /**/ /// <summary>
50          /// Accepts the changes made to this object.
51          /// </summary>
52          /// <remarks>
53          /// After calling this method <see cref="IsDirty"/> and <see cref="IsNew"/> are false.         
54          /// <see cref="IsDeleted"/> flag remain unchanged as it is handled by the parent List.
55          /// </remarks>
56          public   virtual   void  AcceptChanges()
57         ... {
58            this.bindingIsNew = false;
59            this.currentEntityState = EntityState.Unchanged;
60            OnPropertyChanged(string.Empty);
61        }

62
63          /**/ ///<summary>
64          ///  Revert all changes and restore original values.
65          ///  Currently not supported.
66          ///</summary>
67          /// <exception cref="NotSupportedException">This method throws exception.</exception>
68          public   abstract   void  CancelChanges();
69
70          /**/ ///<summary>
71          ///   Marks entity to be deleted.
72          ///</summary>
73          public   virtual   void  MarkToDelete()
74         ... {
75            if (this.currentEntityState != EntityState.Added)
76                this.currentEntityState = EntityState.Deleted;
77        }

78
79
80          /**/ ///<summary>
81          ///   Remove the "isDeleted" mark from the entity.
82          ///</summary>
83          public   virtual   void  RemoveDeleteMark()
84         ... {
85            if (this.currentEntityState != EntityState.Added)
86            ...{
87                this.currentEntityState = EntityState.Changed;
88            }

89        }




Edit 
Interface Implementations 
The entities themselves implement several interfaces to provide the full featured needs of consuming layers. The first two layers are custom .netTiers interfaces, the rest are from the System.ComponentModel and System.Runtime.Serialization namespaces.

Some of these interfaces are : 


IEntityId 
-  Gives exposure to an encapuslated primary key  for  your entity. Supports containment of composite primary keys. 
IEntity
-  A .netTiers  interface  that provides all the functionality required  for  a .netTiers entity. 
IComparable 
-  Implements the ability to compare two entities types. 
ICloneable 
-  Implements the ability to clone an entity 
IEditableObject 
-  Implements the ability to commit or rollback changes to an  object  that  is  used  as  a datasource. 
IComponent 
-  Implements functionality required by all .Net System.ComponetModel Components. 
INotifyPropertyChanged 
-  Notifies subscribed clients that a property value has changed. 
IDataErrorInfo 
-  Provides the functionality to offer custom error information that a user  interface  can bind to. 
IDeserializationCallback 
-  Indicates that a  class   is  to be notified when deserialization of the entire  object  graph has been completed. 
 

Edit 
What about generated views
?  Are they entities ?
Generated views 
object  types are not considered entities, although they share many similar attributes. View objects  do  not maintain state because they currently can not be persisted back into the database. 



Edit 
Entity Validation Rule Engine
One of the most powerful features that .netTiers provides to manage the integrity of your data 
is  the Entity Rule Engine. This implements IDataErrorInfo  in  the EntityBase.generated.cs  class . It provides the framework  for  managing entity business rules and custom error information that a user  interface  can bind to. Controls such  as  the DataGridView automatically detect  this   interface  and provide error icons along with descriptions about the error. 

There are several properties that assist you 
in  managing your business rules. There are several built  in  validators ready to use  out  of the box.




NotNull 
-  Determines the  if  the database column accepts  null  values. 
StringMaxLength 
-  Compares against the column width  for  the property. 
StringRequired 
-  Determines  if  the column allows empty  string  entries. 
MaxWords 
-  Determines whether the property has exceeted the maximum amount of words 
RegexIsMatch 
-  Determines whether current property matches the regular expression 
LessThanOrEqualToValue 
-  Less than or equal to current value of property 
LessThanValue 
-   -  Less than current value of property 
EqualsValue 
-  equals current value of property 
GreaterThanValue 
-  Greater than current value of property 
GreaterThanOrEqualToValue 
-  Greater than or equal to current value of property 
CompareValues 
-  Compares values of T  using  a comparer 
InRange 
-  Ensures T  is  within a min and max of a Range  using  a Comparer. 
 

However, we certainly understand that 
while  those are all very useful, they  do  not cover the spectrum of potentially business rules. There  is  most important aspect of the rule engine that all of the Validators are validated by a  delegate  which  is  called ValidationRuleHandler, through which you can  set  up any ValidationRule, so  long   as  it returns a  bool  value.

The target parameter 
is  the  object  being validated,  while  e  is  a ValidationRuleArgs  object  that contians information about the rule (property to validate, error description). There are a couple of more properties that are of interest. There  is  now a property called IsValid that checks the rules to see  if  any have been broken. You can also  get  all of the broken rules through the BrokenRulesList property  in  your entity.

Validation
/ ValidationRuleHandler.cs 

 
1          /**/ /// <summary>
  2          /// Delegate providing method sig that will process validation rules.
  3          /// </summary>
  4          /// <remarks>
  5          /// <para>
  6          /// The method handler should set the Description attribute of the 
  7          /// <see cref="ValidationRuleArgs"/> parameter so that a meaningful
  8          /// error is returned.
  9          /// </para><para>
10          /// If the data is valid, the method must return true.  If  invalid,
11          /// the Description should be set the false should be returned.
12          /// </para>
13          /// </remarks>
14          public   delegate   bool  ValidationRuleHandler( object  target, ValidationRuleArgs e);

Edit 
Example of Auto
- Generated Rules
.netTiers will automatically detect the rules that apply 
for  the database to maintain data integrity. However it ' s still extremely easy for you to add your own. Here ' s an example of automatically added rules  for  the Customer Entity we were working with.

 1
protected   override   void  AddValidationRules()
 
2 ... {
 
3//Validation rules based on database schema.
 4ValidationRules.AddRule(Validation.CommonRules.NotNull,"CustomerID");
 
5
 6ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
 
7    new Validation.CommonRules.MaxLengthRuleArgs("CustomerID",5));
 
8
 9ValidationRules.AddRule(Validation.CommonRules.NotNull,
"CompanyName");
10
11ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
12    new Validation.CommonRules.MaxLengthRuleArgs("CompanyName",40));
13
14ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
15    new Validation.CommonRules.MaxLengthRuleArgs("ContactName",30));
16
17ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
18    new Validation.CommonRules.MaxLengthRuleArgs("ContactTitle",30));
19
20ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
21    new Validation.CommonRules.MaxLengthRuleArgs("Address",60));
22
23ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
24    new Validation.CommonRules.MaxLengthRuleArgs("City",15));
25
26ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
27    new Validation.CommonRules.MaxLengthRuleArgs("Region",15));
28
29ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
30    new Validation.CommonRules.MaxLengthRuleArgs("PostalCode",10));
31
32ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
33    new Validation.CommonRules.MaxLengthRuleArgs("Country",15));
34
35ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
36    new Validation.CommonRules.MaxLengthRuleArgs("Phone",24));
37
38ValidationRules.AddRule(Validation.CommonRules.StringMaxLength,
39    new Validation.CommonRules.MaxLengthRuleArgs("Fax",24));
40
41}


Edit 
That
' s great, but, how do I add my own rules?
Adding your own rules  is  easy. There are really several ways to  do  it since th properties are exposed. The easiest  is  perhaps to simply  override  the AddRules() method  in  your entities and add your own rules along with ones that were generated  for  you. Here ' s an example of the Orders entity from the Northwind generation.

Orders.cs 
->  The User customizable file  for  your entity  class .

 
1 /**/ /// <summary>
  2 /// Adds custom validation rules to this object.
  3 /// </summary>
 4 protected   override   void  AddValidationRules()
 
5 ... {
 
6    base.AddValidationRules();
 
7
 
8    //Add custom validation rules
 9    ValidationRules.AddRule(Validation.CommonRules.StringRequired, "CustomerID");
10
11     ValidationRules.AddRule(Validation.CommonRules.GreaterThanOrEqualToValue<Decimal?>,  new Validation.CommonRules.CompareValueRuleArgs<Decimal?> ("Freight"0));
12
13     ValidationRules.AddRule(
14        Validation.CommonRules.LessThanOrEqualToValue<Decimal?>
15                new    Validation.CommonRules.CompareValueRuleArgs<Decimal?>
16                    "Freight"200));
17
18 
19    ValidationRules.AddRule(ValidateOrderDate, "OrderDate");
20}

21
22  
23 /**/ /// <summary>
24 /// Validates the order date.
25 /// </summary>
26 /// <param name="target">The target.</param>
27 /// <param name="e">The e.</param>
28 /// <returns></returns>
29 private   bool  ValidateOrderDate( object  target, Validation.ValidationRuleArgs e)
30 ... {
31    if ((this.OrderDate ?? DateTime.MinValue) > DateTime.Today)
32    ...{
33        e.Description = "The Order Date must not be in the future.";
34        return false;
35    }

36
37    return true;
38}


Edit 
So, how 
do  I validate and see the error message ?
The easiest way to validate 
is  when  using  a single entity  is  just to call the IsValid property. It will automatically trigger the validation process. You can also force the validation process by calling Validate();



 
1     Orders o  =   new  Orders();
 
2     o.OrderDate  =   new  DateTime( 2001 8 29 );
 
3     o.ShipAddress  =   " 302 West Main Street " ;
 
4     o.ShipCity  =   " Atlantis " ;
 
5     o.ShipCountry  =   " Anywhere " ;
 
6     o.ShipName  =   " Frank Sanders " ;
 
7     o.ShipPostalCode  =   " 55512 " ;
 
8     o.ShipRegion  =   " Under the Sea " ;
 
9
10  
11     o.Validate();
12      /**/ ///Error property is a newline delimeted list of your broken rules.
13      if  ( ! o.IsValid)
14         lblMessage.Text  =  o.Error;
15
16  
17
18     /**/ ///you can actually access all of the rules that were broken on the entity.
19     foreach (BrokenRule rule  in  o.BrokenRulesList)
20    ... {
21     lblMessage.Text = string.Format("<li>{0} - {1}</li>"
22        rule.Property, rule.Description);
23   }

24
25     /**/ /// Suppose we have a partner vendor that 
26     /// processes orders for us, and we need 
27     /// to validate all of today's orders. 
28     /// Get today's orders and validate them.  
29    TList < Orders >  ordersList  =  GetOrdersFromVender();
30      if  ( ! ordersList.IsValid)
31     ... {
32        StringBuilder sb = new StringBuilder();
33        sb.Append("<li>");
34        foreach(Orders o in ordersList.InvalidItems)
35        ...{
36            sb.Append(o.Error.Replace(" ""<li>"));
37        }

38        lblMessage.Text = sb.ToString();
39
40    }




Overall, the important thing to remember 
is  that since the Rules engine uses delegates, which means that your logic can live any place you would like it to. There will be more coverage with complex business processes and validation  in  the Component Layer chapter.

Edit 
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      /**/ ///Index Of, Get's the location of the order in the list
  11      int  index  =  ordersList.IndexOf(order);
 
12
 
13      /**/ ///FindIndex
  14      ///Returns the integer value if 
  15      ///one of the criteria matches your predicate
  16     ordersList.FindIndex(
 
17          delegate (Orders orders)
 
18         ... {
 
19            return orders.RequiredDate < DateTime.Today.AddDays(2);
 
20        }
);
 
21  
 
22
 
23      /**/ ///Insert
  24      ///Useful if you want to insert an order in a specific location
  25      if  (index  <   0 )
 
26         ordersList.Insert( 0 , order);
 
27  
 
28      /**/ ///Add
  29      ///Appends an order to the list
  30     ordersList.Add(order);
 
31
 
32  
 
33      /**/ ///AddNew
  34      ///Appends a new order to the list
  35     ordersList.AddNew();
 
36     ordersList[ordersList.Count  -   1 ].OrderDate  =  DateTime.Today;
 
37
 
38  
 
39      /**/ ///RemoveEntity
  40      ///Removes the order from the list and places it in DeletedItems
  41     ordersList.RemoveEntity(order);
 
42  
 
43      /**/ ///RemoveAt
  44      ///Removes the first entry of the list
  45     ordersList.RemoveAt( 0 );
 
46  
 
47      /**/ ///RemoveAt
  48      ///Removes the entity where it exists
  49     ordersList.Remove(order);
 
50  
 
51      /**/ ///ListChanged
  52      ///Fires an event when the list has changed
  53     ordersList.ListChanged  +=  
 
54        new  System.ComponentModel.ListChangedEventHandler(ordersList_ListChanged);
 
55
 
56  
 
57      /**/ ///IsDeletedCount
  58      ///Returns the count of the DeletedItems Collection
  59      int  deletedCount  =  ordersList.IsDeletedCount;
 
60     Debug.Assert(deletedCount  ==  ordersList.DeletedItems.Count);
 
61  
 
62      /**/ ///IsDirtyCount
  63      ///Returns the count of the items that have an 
  64      ///EntityState == EntityState.Changed
  65      int  dirtyCount  =  ordersList.IsDirtyCount;
 
66     Response.Write( string .Format( " You have modified {0} entities. " ,dirtyCount));
 
67  
 
68      /**/ ///IsNewCount
  69      ///Returns the count of the items that have an 
  70      ///EntityState == EntityState.Added
  71      int  newCount   =  ordersList.IsNewCount;
 
72     Response.Write( string .Format( " You have added {0} entities. " , newCount));
 
73  
 
74      /**/ ///FindAllBy
  75      ///Returns a new List of Entities that 
  76      /// match the FindAllByType
  77      ///FindAllByType.Contains, FindAllBy.StartsWith, FindAllByType.EndsWith
  78     TList < Orders >  sList  =  ordersList.FindAllBy(TList < Orders > .FindAllByType.StartsWith, 
 
79                         OrdersColumn.ShipCity,  " Atl " );
 
80  
 
81     TList < Orders >  cList  =  ordersList.FindAllBy(TList < Orders > .FindAllByType.Contains,
 
82                         OrdersColumn.ShipCity,  " ant " );
 
83
 
84      TList < Orders >  eList  = ordersList.FindAllBy(TList < Orders > .FindAllByType.EndsWith,
 
85                         OrdersColumn.ShipCity,  " tis " );
 
86
 
87      /**/ ///FindAll
  88      ///Returns a new List of Entities that match using the Table Enum Columns
  89     TList < Orders >  eqList  =  
 
90         ordersList.FindAll(OrdersColumn.ShipCity,  " Atlantis " );
 
91
 
92  
 
93      /**/ ///FindAll
  94      ///Returns a new List of Entities using a predicate
  95     TList < Orders >  eqList2  =  ordersList.FindAll(
 
96          delegate (Orders o2)... {
 
97            return 
 
98                o2.OrderDetailsCollection.Count > 0 &&
 
99                o2.OrderDate == DateTime.Today;
100        }
);
101  
102      /**/ ///Exists
103      ///Returns a bool if one of the criteria matches your predicate
104      if  (ordersList.Exists(
105          delegate (Orders o3)
106         ... {
107            return
108                o3.OrderDetailsCollection.Count > 0 &&
109                o3.OrderDate == DateTime.Today;
110        }
))
111     ... {
112        Response.Write("There are orders today");
113    }

114  
115      /**/ ///ToArray
116      ///Creates an orders array from a list
117     Orders[] orderArray  =  ordersList.ToArray();
118  
119      /**/ ///ToDataSet
120      ///Creates a DataSet with children relationships from your TList.
121     DataSet ds  =  ordersList.ToDataSet( true );
122  
123      /**/ /// Filter as a string
124      /// Creates a view inside of your list using a case sensitive filter
125      /// Great for cached items that you need to show
126      /// different sets of entities based on criteria.
127     ordersList.Filter  =   " ShipCity = 'Atlantis' " ;
128     ordersList.ApplyFilter();
129             ordersList.ForEach(
130              delegate (Orders filteredOrder)
131             ... {
132                Debug.Assert(filteredOrder.ShipCity == "Atlantis");   
133            }
);
134  
135      /**/ ///To Remove the filter, you simply call ResetFilter;
136     ordersList.RemoveFilter();
137
138      /**/ /// Filter using a Predicate delegate
139      /// Great for needing to filter on items that 
140      /// different sets of entities based on criteria.
141     ordersList.ApplyFilter(GetValidAtlantisOrders);
142     ordersList.ForEach(
143      delegate (Orders filteredOrder)
144     ... {
145        Debug.Assert(filteredOrder.IsValid 
146            && filteredOrder.ShipCity == "Atlantis");
147    }
);
148
149 } // End Page_Load
150
151
152      /**/ /// <summary>
153      /// Gets the valid atlantis orders.
154      /// </summary>
155      /// <param name="o">The o.</param>
156      /// <returns></returns>
157      public   bool  GetValidAtlantisOrders(Orders o)
158     ... {
159        return (o.IsValid 
160                && o.ShipCity == "Atlantis" 
161                && o.OrderDetailsCollection.Count > 0
162                && o.OrderDetailsCollection.IsValid);
163    }

164  
165      void  ordersList_ListChanged( object  sender,                                            System.ComponentModel.ListChangedEventArgs e)
166     ... {
167        throw new Exception("The method or operation is not implemented.");
168    }

169  
170    /**/ /// <summary>
171    /// Gets the orders from vendor. Stub method, does nothing. 
172    /// </summary>
173    /// <returns></returns>
174    public  TList  < Orders >  GetOrdersFromVendor()
175   ... {
176     //Get Some orders from a vendor
177       return new TList<Orders>();
178  }
   
179 }

Edit 
Entity Management Framework:
In any application there are often several aspects of your application that you commonly have to 
do   in  order to optimize your application.

Edit 
EntityFactoryBase
The EntityFactoryBase 
is  a creational construct that exists to assist the creation of entities of an unknown type at runtime. Entities are / were normally created  in  the DataRepository  in  a given EntityProvider ' s Fill method. So if I had DataRepository.MyEntityProvider, there would be a method called Fill that took an IDataReader, an TList (EntityCollection) and a row params. This method is actually going to hydrate the entities when coming back from the DataRepository.

This version of the templates allow you to create component business objects which inherit from the entity objects. Since these component objects live 
in  the tier on top of the Data Access Layer and Entities. Since the DataRepository creates entities  for  usage, it ' s not possible to create those types because the DAL deosn ' t know about the smart component business objects, only the Entity DTO objects. The role the EntityFactory  is  used  for   is  you have the ability to define which factory will be used to create your objects to be filled  in  the app / web.config. 

Example:

1entityFactoryType
= " Northwind.Entities.EntityFactory " ;
2 //  OR 
3entityFactoryType = " Northwind.Entities.ComponentEntityFactory " ;

Each factory will use the 
namespace  of the factory to create unkonwn types at runtime  using  an Activator. This type discovery  is  cached and so you only face a perf hit once.

There are events that you can subscribe to during 
this  process to inject some logic before the  object   is  created and just after it ' s created but before being hydrated. This is useful if you wanted to attach your own events to the entity. 

Edit 
EntityCache
The EntityCache 
class  manages the lifetime of entities that you would like to not have to be queried  for  all the time. In reality,  this   class  simply wraps the Enterprise Library Cache. EntLib offers a full featured and configurable  object  cache. The entity cache can be used by any  object , and does not have to be an entity. More info can be found here:

You don
' t "Have" to configure the cache to work, .netTiers will generate a default cache configuration at runtime if one does not exist, but it ' s recommended that you  do  create a configuration  for  your caching block to optimize the cache settings  for  your application. The entity cache can easily be configured by pointing your Enterprise Library Configurator tool at your app / web.config. We ' ve also recently started including a sample default settings entlib.config in the MyNamespace.UnitTest project. 

Edit 
IEntityCacheItem
When 
this  marker  interface   is  applied to an entity, the entity will automatically be placed into cache. The  interface  provides lifetime and callback parameters used to manage the caching of your entities. This  is  an  interface  that you would have to apply yourself to the entity at the concrete  class  level.

Edit 
EntityLocator
The EntityLocator sits on top of the Locator 
class  of the Microsoft Patterns and Practices Group ' s ObjectBuilder Framework. The locator is responsible for creating a WeakReference ' d Object Store so that  as  your application  is  handling a high volume of entities, which many are of the same record, we will  return  to you the same  object   for  all references until that entity  is  persisted to the DataRepository. Combining  this  feature with Optimistic Concurrency with a Timestamp on your Table, you ' ll end up saving quite a bit on memory consumption. And for those that might not know, a weak reference means that the objects will still be garbage collected as soon as there are no more actual references to that entity any longer.

This feature has to be enabled 
in  the app / web.config under enableEntityTracking = " true/false "  

Edit 
EntityManager
The EntityManager 
is  the glue that holds it all together, and should be considered the entry point to most of these features, with the exception of the EntityCache. When an  object   is  about to be created, and DataRepository.Provider.EntityTracking  is  enabled, the EntityManager  get ' s called. The EntityManager contains a single EntityLocator object and a collection of EntityCache objects, for all of your different entity cache providers. Most likely though, there will only be a single EntityCache object in there.

The EntityManager contains a LocateOrCreate method that determine 
if  an entity already exists and  is  currently being referenced,  if  so, then  return  that entity, otherwise, create a  new  one  using  the entity factory defined and begin tracking the entity. 

There are several yet to be implemented features which we have 
in  mind  for  the EntityManager such  as  managing meta data amongst the entities and being able to determine relationship boundaries at runtime.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值