I tested it with 4 different database implementations that I have, if you guys could give it a spin and let me know your experience with the changes, that'd be awesome.
Change Log regarding this:
- [ENH] Auto-Fill of new id's for junction entities when the source objects are created for their respective primary keys.
protected void Page_Load(object sender, EventArgs e)
{
LeftTable left = new LeftTable();
left.LeftColumnName = "MyLeftName8";
RightTable right = new RightTable();
right.RightColumnName = "MyRightName9";
RightTable right2 = new RightTable();
right2.RightColumnName = "MyRightName10";
RightTable right3 = new RightTable();
right3.RightColumnName = "MyRightName11";
left.RightTableCollection_From_RightLeftJunction.Add(right);
left.RightTableCollection_From_RightLeftJunction.Add(right2);
left.RightTableCollection_From_RightLeftJunction.Add(right3);
//Add the junction table entities, and add references to the newly created entities.
//the identity mappings will occur as each one is updated automatically in the provider.
RightLeftJunction both = new RightLeftJunction();
both.LeftColumn1PKSource = left;
both.RightTablePKSource = right;
RightLeftJunction both2 = new RightLeftJunction();
both2.LeftColumn1PKSource = left;
both2.RightTablePKSource = right2;
RightLeftJunction both3 = new RightLeftJunction();
both3.LeftColumn1PKSource = left;
both3.RightTablePKSource = right3;
left.RightLeftJunctionCollection.Add(both);
left.RightLeftJunctionCollection.Add(both2);
left.RightLeftJunctionCollection.Add(both3);
using (TransactionManager tm = DataRepository.Provider.CreateTransaction())
{
tm.BeginTransaction();
DataRepository.LeftTableProvider.DeepSave(tm, left);
tm.Commit();
}
}
- [ENH] Deep [Loading/Saving] Events now expose everything about it's current deep session, including canceling and skipping items in the session. Including the ability to cancel your session. There is a new class called NS.Data.Bases.EntityProviderBaseCore<Entity, EntityKey>.DeepSessionEventArgs
-- example:
DataRepository.LeftTableProvider.DeepSaving += new NS.Data.Bases.EntityProviderBaseCore<LeftTable,LeftTableKey>.DeepSavingEventHandler( LeftTableProvider_DeepSaving);
DataRepository.LeftTableProvider.DeepSave(tm, left);
...
private void LeftTableProvider_DeepSaving(object sender, chimbaloo.Data.Bases.DeepSessionEventArgs e)
{
Writer(e.Skip);
Writer(e.Cancel);
Writer(e.DeepTypeValue.ToString());
Writer(e.DeepSession.Count);
Writer(e.CurrentEntity != null ? e.CurrentEntity.GetType().FullName : "");
Writer(e.CurrentEntityList != null ? e.GetType().FullName : "");
Writer(e.CurrentTypePropertyKey);
}
- [ENH] Created DeepSession class using a weak reference to monitor loaded entities and lists based on key.
-- internal changes, DeepSession inherits from List<string> to store the types to load, but also uses a WeakReferenceDictionary for the objects.
- [REF] Changed Deep* from depth first to breadth first, using a delegate mapping to the deep call.
-- now for each call, after a Load or Save is performed, it checks to see if it can go deep, if possible, then it adds a delegate handle of the call: This way the entire set of local properties can be loaded prior to going deep. This was an issue, when you had a M:M relationship being loaded and itself contains a relationships back to another child object, and it would fill the other child within the M:M instead of inside it's sibling property.
Dictionary<Delegate, object> deepHandles = new Dictionary<Delegate, object>();
...
deepHandles.Add(
(DeepLoadHandle< OrderDetails >) DataRepository.OrderDetailsProvider.DeepLoad,
new object[] { transactionManager, entity.OrderDetailsCollection, deep, deepLoadType, childTypes, innerList }
);
...
foreach(KeyValuePair<Delegate, object> pair in deepHandles)
{
pair.Key.DynamicInvoke((object[])pair.Value);
}
- [REF] Removed DeepLoad M:M methods from the ability to call nested levels of DeepLoading, the M:M property itself can be loaded in a deep load, but it doesn't recursively follow down that branch (easily fall into cyclical branches).
-- Again, similar to the problem above, a M:M relationship will always have a nested child property back to the parent. So, even tracking loads, lots of wasted CPU cycles were being spent in those nested branches, so it made all the sense to simply remove the ability for the M:M properties in a type to not be deep loaded, since the intent is for it to be loaded locally and not within the nested m:m relationship.
- [ENH] Added a more likely to be unique GetHashCode() implementation for Entities.
-- This is useful for the loading process and possibly could be extended to be used as the EntityTrackingKey in future versions.
- [ENH] Enhanced the EntityTrackingKey to use a pipe delimeter between keys in composite key types
-- This avoids collisions with composite keys using integer values
Robert Hinojosa
-------------------------------------
Member of the Codesmith Tools, .netTiers, teams
http://www.nettiers.com-------------------------------------