Пример #1
0
        /// <summary>
        /// Retrieves keys of changed entities (added or modified) since moment.
        /// <param name="source">The DbSet of requested entities</param>
        /// <param name="context">The <see cref="DbContext"/> Instance of you DBContext to be configured.</param>
        /// <param name="sinceMoment">Time period after which you need to get added or changed data</param>
        /// <returns>Filtered DbSet</returns>
        /// </summary>
        public static IQueryable <TSource> AddedOrChanged <TSource>(this IQueryable <TSource> source, DbContext context, DateTime sinceMoment) where TSource : class
        {
            var trackableEntities = DbContextExtention.GetTrackInfoRuntime(context.GetType());

            if (trackableEntities != null && trackableEntities.ContainsKey(typeof(TSource)))
            {
                var  trackData      = trackableEntities[typeof(TSource)];
                var  propTrackDbSet = context.GetType().GetProperties().Where(v => v.Name == trackData.NameOfTrackDbSet).First();
                var  trackSet       = propTrackDbSet.GetValue(context);
                var  entityKeys     = context.Model.GetEntityTypes(typeof(TSource)).First().GetKeys();
                Type trackType      = trackData.TrackType;

                var trackKeys = context.Model.GetEntityTypes(trackType).First().GetKeys();

                Func <object, bool> findPredicate = (a) => {
                    var res = StateOfEntity.Modified.Equals(a.GetType().GetProperty("StateOwner").GetValue(a)) ||
                              StateOfEntity.Added.Equals(a.GetType().GetProperty("StateOwner").GetValue(a));
                    return(res && (DateTime)a.GetType().GetProperty("Date").GetValue(a) > sinceMoment);
                };
                Func <TSource, Dictionary <string, object> > innerKeySelector = (a) => {
                    Dictionary <string, object> keyVals = new Dictionary <string, object>();
                    foreach (var k in entityKeys)
                    {
                        foreach (var p in k.Properties)
                        {
                            keyVals.Add(p.Name, p.PropertyInfo.GetValue(a));
                        }
                    }
                    return(keyVals);
                };
                Func <object, Dictionary <string, object> > outerKeySelector = (a) => {
                    Dictionary <string, object> keyVals = new Dictionary <string, object>();
                    foreach (var k in trackKeys)
                    {
                        foreach (var p in k.Properties)
                        {
                            keyVals.Add(p.Name, p.PropertyInfo.GetValue(a));
                        }
                    }
                    return(keyVals);
                };
                Func <object, TSource, TSource> resultSelector = (a, b) => {
                    return(b);
                };
                var foundedData = (trackSet as IQueryable <object>).Where <object>(findPredicate);

                return(foundedData
                       .Join <object, TSource, Dictionary <string, object>, TSource>(source, outerKeySelector, innerKeySelector, resultSelector, new KeyComparer()).AsQueryable <TSource>());
            }
            return(source);
        }
Пример #2
0
        /// <summary>
        /// Retrieves keys of entities deleted since moment.
        /// <param name="source">The DbSet of requested entities</param>
        /// <param name="context">The <see cref="DbContext"/> Instance of you DBContext to be configured.</param>
        /// <param name="sinceMoment">Time period after which you need to get deleted data</param>
        /// <returns>Filtered DbSet</returns>
        /// </summary>
        public static IQueryable <TSource> Deleted <TSource>(this IQueryable <TSource> source, DbContext context, DateTime sinceMoment) where TSource : class
        {
            var trackableEntities = DbContextExtention.GetTrackInfoRuntime(context.GetType());

            if (trackableEntities != null && trackableEntities.ContainsKey(typeof(TSource)))
            {
                var  trackData      = trackableEntities[typeof(TSource)];
                var  propTrackDbSet = context.GetType().GetProperties().Where(v => v.Name == trackData.NameOfTrackDbSet).First();
                var  trackSet       = propTrackDbSet.GetValue(context);
                Type trackType      = trackData.TrackType;
                Func <object, bool> findPredicate = (a) => {
                    var res = StateOfEntity.Deleted.Equals(a.GetType().GetProperty("StateOwner").GetValue(a));
                    return(res && (DateTime)a.GetType().GetProperty("Date").GetValue(a) > sinceMoment);
                };
                return((trackSet as IQueryable <object>).Where <object>(findPredicate).AsQueryable <object>().FromTrack <object, TSource>());
            }
            return(source);
        }
Пример #3
0
        /// <summary>
        /// Create extention for track entity change.
        /// </summary>
        /// <param name="modelBuilder">The <see cref="ModelBuilder"/> to enable track and save entity change.</param>
        /// <param name="contextType">The type of DbContext.</param>
        /// <returns>The <see cref="ModelBuilder"/> had enabled track and save entity change feature.</returns>
        public static ModelBuilder CreateDataChangeTracking(this ModelBuilder modelBuilder, Type contextType)
        {
            FieldInfo trackField = contextType.GetField("_isRuntimeConstructedForTrack", BindingFlags.Static | BindingFlags.NonPublic);

            if (trackField != null)
            {
                var trackableEntities = DbContextExtention.GetTrackInfo(contextType);
                if (trackableEntities != null)
                {
                    foreach (var entityType in (Dictionary <Type, EntityPropsForTransfer>)trackableEntities)
                    {
                        modelBuilder.Entity(entityType.Value.TrackType).HasNoDiscriminator();
                        modelBuilder.Entity(entityType.Value.TrackType).HasKey(entityType.Value.Props.Keys.ToArray());
                        modelBuilder.Entity(entityType.Value.TrackType).Property("Date").HasValueGenerator <ValueGeneratorDataNow>();
                        modelBuilder.Entity(entityType.Value.TrackType).HasIndex("Date").IsUnique(false);
                        modelBuilder.Entity(entityType.Value.TrackType).HasIndex("StateOwner").IsUnique(false);
                    }
                }
            }
            return(modelBuilder);
        }