Esempio n. 1
0
        /// <summary>
        /// Populate the sub entities of fieldTestList
        /// </summary>
        /// <param name="fieldTests"></param>
        /// <param name="toPopulate"></param>
        public override void Populate(IEnumerable <FieldTest> fieldTests, Flags toPopulate)
        {
            Log("Populate", fieldTests.GetIdenties(), toPopulate);

            // Implement breadth first loading of related entities.
            // Any entity that has been requested to be loaded, should be loaded at this level where possible.
            // Remove all sub entity types that this entity relates to directly.
            Flags stillToPopulate = toPopulate;

            stillToPopulate = stillToPopulate.Remove(EntityType.Widget);
            stillToPopulate = stillToPopulate.Remove(EntityType.Widget);

            // Get parent entities: Widget
            if ((toPopulate & EntityType.Widget) == EntityType.Widget)
            {
                // Grab the ids for the ones that actually need populating
                IEnumerable <FieldTest> toBePopulated = fieldTests.Where(entity => entity.ForeignKeyFieldWidgetRequiresPopulation);
                int[] idsToLoad = toBePopulated.Select(entity => entity.ForeignKeyField).ToList().ToArray();

                // And load the sub entities for those ones.
                WidgetList parentWidgetList = toBePopulated.Count() > 0
                    ? WidgetRepo.Get(idsToLoad, stillToPopulate)
                    : new WidgetList();
                Dictionary <int, Widget> widgetListById = parentWidgetList.MapById;

                // Now go over all the entites. For ones that need popualting, populate entities
                // directly. For those already populated, make a check on sub entities to ensure
                // they are loaded to the required level
                WidgetList toBeChecked = new WidgetList();
                foreach (FieldTest fieldTest in fieldTests)
                {
                    if (fieldTest.ForeignKeyFieldWidgetRequiresPopulation)
                    {
                        fieldTest.ForeignKeyFieldWidget =
                            widgetListById.ContainsKey(fieldTest.ForeignKeyField)
                                                        ? widgetListById[fieldTest.ForeignKeyField]
                                                        : null;
                    }
                    else if (fieldTest.ForeignKeyFieldWidgetPopulated)
                    {
                        toBeChecked.Add(fieldTest.ForeignKeyFieldWidget);
                    }
                }

                // If there's any "to be checked" (because they were already loaded) let the entiies own
                // repo do whatever checks it needs to do
                if (toBeChecked.Count > 0)
                {
                    WidgetRepo.Populate(toBeChecked, stillToPopulate);
                }
            }

            // Get parent entities: Widget
            if ((toPopulate & EntityType.Widget) == EntityType.Widget)
            {
                // Grab the ids for the ones that actually need populating
                IEnumerable <FieldTest> toBePopulated = fieldTests.Where(entity => entity.ForeignKeyFieldNullableWidgetRequiresPopulation);
                int[] idsToLoad = toBePopulated.Select(entity => entity.ForeignKeyFieldNullable.Value).ToList().ToArray();

                // And load the sub entities for those ones.
                WidgetList parentWidgetList = toBePopulated.Count() > 0
                    ? WidgetRepo.Get(idsToLoad, stillToPopulate)
                    : new WidgetList();
                Dictionary <int, Widget> widgetListById = parentWidgetList.MapById;

                // Now go over all the entites. For ones that need popualting, populate entities
                // directly. For those already populated, make a check on sub entities to ensure
                // they are loaded to the required level
                WidgetList toBeChecked = new WidgetList();
                foreach (FieldTest fieldTest in fieldTests)
                {
                    if (fieldTest.ForeignKeyFieldNullableWidgetRequiresPopulation)
                    {
                        fieldTest.ForeignKeyFieldNullableWidget =
                            widgetListById.ContainsKey(fieldTest.ForeignKeyFieldNullable.Value)
                                                        ? widgetListById[fieldTest.ForeignKeyFieldNullable.Value]
                                                        : null;
                    }
                    else if (fieldTest.ForeignKeyFieldNullableWidgetPopulated)
                    {
                        toBeChecked.Add(fieldTest.ForeignKeyFieldNullableWidget);
                    }
                }

                // If there's any "to be checked" (because they were already loaded) let the entiies own
                // repo do whatever checks it needs to do
                if (toBeChecked.Count > 0)
                {
                    WidgetRepo.Populate(toBeChecked, stillToPopulate);
                }
            }
        }
        /// <summary>
        /// Save (insert/update) a Thing into the store
        /// </summary>
        /// <param name="entitiesBeingHandled">Entities already being saved further up the save stack</param>
        /// <param name="things">The Things to save</param>
        /// <param name="toSave">Entity types to cascade to, if they are loaded</param>
        internal void Save(List <Entity> entitiesBeingHandled, Flags toSave, params Thing[] things)
        {
            if (things == null)
            {
                throw new ArgumentNullException("things");
            }
            Log("Save", things.Select <Thing, int>(entity => entity.Identity).ToArray <int>(), EntityType.None);

            // Copy the list of entities being handled, and add this new set of entities to it.
            // We're handling those now.
            List <Entity> entitiesNowBeingHandled = new List <Entity>(entitiesBeingHandled);

            entitiesNowBeingHandled.AddRange(things);

            // Loop over each entity and save it.
            foreach (Thing thing in things)
            {
                // Already being saved higher up the stack?
                if (entitiesBeingHandled.ContainsEntity(thing))
                {
                    continue;
                }

                // Allow derived/partial class to do extra work
                OnBeforeSaveEntity(thing);

                bool saved = false;

                try
                {
                    // Save the entity
                    if (thing.IsNew)
                    {
                        this.Mapper.Insert("InsertThing", thing);
                        saved = true;
                    }
                    else if (thing.IsChanged)
                    {
                        if (this.Mapper.Update("UpdateThing", thing) != 1)
                        {
                            ThrowThingEntityException(thing.Identity);
                        }
                        saved = true;
                    }
                }
                catch (Exception ex)
                {
                    throw EntityLogger.WriteUnexpectedException(
                              ex,
                              "Failed to insert/update Entity",
                              Category.EntityFramework,
                              thing);
                }

                // Save child entities... update their key to us
                if ((toSave & EntityType.Widget) == EntityType.Widget &&
                    thing.WidgetListPopulated)
                {
                    foreach (Widget childWidget in thing.WidgetList)
                    {
                        childWidget.ThingId = thing.Identity;
                        if (!entitiesBeingHandled.ContainsEntity(childWidget))
                        {
                            if (childWidget.IsDeleted)
                            {
                                WidgetRepo.Delete(entitiesNowBeingHandled, toSave, childWidget);
                            }
                            else
                            {
                                WidgetRepo.Save(entitiesNowBeingHandled, toSave, childWidget);
                            }
                        }
                    }
                }

                // Post save protocol
                if (saved)
                {
                    // Allow derived/partial class to do extra work
                    OnAfterSaveEntity(thing);

                    thing.Reset();

                    //The insert/update will have resulted in a new database_update row, inform interested parties
                    RaiseModelChanged();
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Save (insert/update) a FieldTest into the store
        /// </summary>
        /// <param name="entitiesBeingHandled">Entities already being saved further up the save stack</param>
        /// <param name="fieldTests">The FieldTests to save</param>
        /// <param name="toSave">Entity types to cascade to, if they are loaded</param>
        internal void Save(List <Entity> entitiesBeingHandled, Flags toSave, params FieldTest[] fieldTests)
        {
            if (fieldTests == null)
            {
                throw new ArgumentNullException("fieldTests");
            }
            Log("Save", fieldTests.Select <FieldTest, int>(entity => entity.Identity).ToArray <int>(), EntityType.None);

            // Copy the list of entities being handled, and add this new set of entities to it.
            // We're handling those now.
            List <Entity> entitiesNowBeingHandled = new List <Entity>(entitiesBeingHandled);

            entitiesNowBeingHandled.AddRange(fieldTests);

            // Loop over each entity and save it.
            foreach (FieldTest fieldTest in fieldTests)
            {
                // Already being saved higher up the stack?
                if (entitiesBeingHandled.ContainsEntity(fieldTest))
                {
                    continue;
                }

                // Allow derived/partial class to do extra work
                OnBeforeSaveEntity(fieldTest);

                // Save parent entity... so we can update our key to it
                if ((toSave & EntityType.Widget) == EntityType.Widget &&
                    fieldTest.ForeignKeyFieldWidgetPopulated)
                {
                    if (!entitiesBeingHandled.ContainsEntity(fieldTest.ForeignKeyFieldWidget))
                    {
                        WidgetRepo.Save(entitiesNowBeingHandled, toSave, fieldTest.ForeignKeyFieldWidget);
                        fieldTest.ForeignKeyField = fieldTest.ForeignKeyFieldWidget.Identity;
                    }
                }

                // Save parent entity... so we can update our key to it
                if ((toSave & EntityType.Widget) == EntityType.Widget &&
                    fieldTest.ForeignKeyFieldNullableWidgetPopulated)
                {
                    if (!entitiesBeingHandled.ContainsEntity(fieldTest.ForeignKeyFieldNullableWidget))
                    {
                        WidgetRepo.Save(entitiesNowBeingHandled, toSave, fieldTest.ForeignKeyFieldNullableWidget);
                        fieldTest.ForeignKeyFieldNullable = fieldTest.ForeignKeyFieldNullableWidget.Identity;
                    }
                }

                bool saved = false;

                try
                {
                    // Save the entity
                    if (fieldTest.IsNew)
                    {
                        this.Mapper.Insert("InsertFieldTest", fieldTest);
                        saved = true;
                    }
                    else if (fieldTest.IsChanged)
                    {
                        if (this.Mapper.Update("UpdateFieldTest", fieldTest) != 1)
                        {
                            ThrowFieldTestEntityException(fieldTest.Identity);
                        }
                        saved = true;
                    }
                }
                catch (Exception ex)
                {
                    throw EntityLogger.WriteUnexpectedException(
                              ex,
                              "Failed to insert/update Entity",
                              Category.EntityFramework,
                              fieldTest);
                }

                // Post save protocol
                if (saved)
                {
                    // Allow derived/partial class to do extra work
                    OnAfterSaveEntity(fieldTest);

                    fieldTest.Reset();

                    //The insert/update will have resulted in a new database_update row, inform interested parties
                    RaiseModelChanged();
                }
            }
        }