/// <summary>
 /// Prefer WithExpressionFrom to keep dependencies between modules clean!.
 /// </summary>
 public static FluentInclude <F> WithExpressionTo <F, T>(this FluentInclude <F> fi, DynamicQueryManager dqm, Expression <Func <F, Lite <T> > > lambdaToMethodOrProperty, Func <string> niceName)
     where F : Entity
     where T : Entity
 {
     dqm.RegisterExpression(lambdaToMethodOrProperty, niceName);
     return(fi);
 }
Esempio n. 2
0
 public static FluentInclude <T> WithTree <T>(this FluentInclude <T> include, Func <T, MoveTreeModel, T>?copy = null) where T : TreeEntity, new()
 {
     RegisterExpressions <T>();
     RegisterOperations <T>(copy);
     include.WithUniqueIndex(n => new { n.ParentRoute, n.Name });
     return(include);
 }
 /// <summary>
 /// Prefer WithExpressionFrom to keep dependencies between modules clean!. Uses NiceName as niceName.
 /// </summary>
 public static FluentInclude <F> WithExpressionTo <F, T>(this FluentInclude <F> fi, DynamicQueryManager dqm, Expression <Func <F, T> > lambdaToMethodOrProperty)
     where F : Entity
     where T : Entity
 {
     dqm.RegisterExpression(lambdaToMethodOrProperty, () => typeof(T).NiceName());
     return(fi);
 }
 /// <summary>
 /// Prefer WithExpressionFrom to keep dependencies between modules clean!.
 /// </summary>
 public static FluentInclude <F> WithExpressionTo <F, T>(this FluentInclude <F> fi, Expression <Func <F, T?> > lambdaToMethodOrProperty, Func <string> niceName)
     where F : Entity
     where T : Entity
 {
     QueryLogic.Expressions.Register(lambdaToMethodOrProperty, niceName);
     return(fi);
 }
 /// <summary>
 /// Prefer WithExpressionFrom to keep dependencies between modules clean!. Uses typeof(T) NiceName as niceName.
 /// </summary>
 public static FluentInclude <F> WithExpressionTo <F, T>(this FluentInclude <F> fi, Expression <Func <F, T?> > lambdaToMethodOrProperty)
     where F : Entity
     where T : Entity
 {
     QueryLogic.Expressions.Register(lambdaToMethodOrProperty, () => typeof(T).NiceName());
     return(fi);
 }
Esempio n. 6
0
        public static FluentInclude <T> WithVirtualMListInitializeOnly <T, L>(this FluentInclude <T> fi,
                                                                              Func <T, MList <L> > getMList,
                                                                              Expression <Func <L, Lite <T> > > getBackReference,
                                                                              Action <L, T> onSave = null)
            where T : Entity
            where L : Entity
        {
            Action <L, Lite <T> > setter = null;
            var sb = fi.SchemaBuilder;

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                if (GraphExplorer.IsGraphModified(getMList(e)))
                {
                    e.SetModified();
                }
            };
            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                var mlist = getMList(e);

                if (!GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (setter == null)
                {
                    setter = CreateSetter(getBackReference);
                }

                mlist.ForEach(line => setter(line, e.ToLite()));
                if (onSave == null)
                {
                    mlist.SaveList();
                }
                else
                {
                    mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line))
                                            {
                                                onSave(line, e);
                                            }
                                  });
                }
                var priv = (IMListPrivate)mlist;
                for (int i = 0; i < mlist.Count; i++)
                {
                    if (priv.GetRowId(i) == null)
                    {
                        priv.SetRowId(i, mlist[i].Id);
                    }
                }
                mlist.SetCleanModified(false);
            };

            return(fi);
        }
Esempio n. 7
0
        public static FluentInclude <T> WithDelete <T>(this FluentInclude <T> fi, DeleteSymbol <T> delete)
            where T : Entity
        {
            new Graph <T> .Delete(delete)
            {
                Delete = (e, _) => e.Delete()
            }

            .Register();
            return(fi);
        }
Esempio n. 8
0
        public static FluentInclude <T> WithConstruct <T>(this FluentInclude <T> fi, ConstructSymbol <T> .Simple construct, Func <object[], T> constructFunction)
            where T : Entity
        {
            new Graph <T> .Construct(construct)
            {
                Construct = constructFunction
            }

            .Register();
            return(fi);
        }
Esempio n. 9
0
        public static FluentInclude <T> WithConstruct <T>(this FluentInclude <T> fi, ConstructSymbol <T> .Simple construct)
            where T : Entity, new()
        {
            new Graph <T> .Construct(construct)
            {
                Construct = (_) => new T()
            }

            .Register();
            return(fi);
        }
Esempio n. 10
0
 public static FluentInclude <T> WithQuery <T, Q>(this FluentInclude <T> fi, DynamicQueryManager dqm, Expression <Func <T, Q> > simpleQuerySelector, Action <AutoDynamicQueryCore <Q> > modifyQuery)
     where T : Entity
 {
     dqm.RegisterQuery <Q>(typeof(T), () =>
     {
         var autoQuery = DynamicQueryCore.Auto(Database.Query <T>().Select(simpleQuerySelector));
         modifyQuery(autoQuery);
         return(autoQuery);
     });
     return(fi);
 }
Esempio n. 11
0
        public static FluentInclude <T> WithSave <T>(this FluentInclude <T> fi, ExecuteSymbol <T> saveOperation)
            where T : Entity
        {
            new Graph <T> .Execute(saveOperation)
            {
                AllowsNew = true,
                Lite      = false,
                Execute   = (e, _) => { }
            }

            .Register();
            return(fi);
        }
Esempio n. 12
0
 public static FluentInclude <T> WithDeletePart <T, L>(this FluentInclude <T> fi, Expression <Func <T, Lite <L> > > relatedEntity)
     where T : Entity
     where L : Entity
 {
     fi.SchemaBuilder.Schema.EntityEvents <T>().PreUnsafeDelete += query =>
     {
         var toDelete = query.Select(relatedEntity).ToList().NotNull().Distinct().ToList();;
         return(new Disposable(() =>
         {
             Database.DeleteList(toDelete);
         }));
     };
     return(fi);
 }
Esempio n. 13
0
        public static FluentInclude <T> WithSave <T>(this FluentInclude <T> fi, ExecuteSymbol <T> saveOperation)
            where T : Entity
        {
            new Graph <T> .Execute(saveOperation)
            {
                CanBeNew      = true,
                CanBeModified = true,
                Execute       = (e, _) => { }
            }

            .Register();

            return(fi);
        }
Esempio n. 14
0
 public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                         Expression <Func <T, MList <L> > > mListField,
                                                         Expression <Func <L, Lite <T>?> > backReference,
                                                         ExecuteSymbol <L> saveOperation,
                                                         DeleteSymbol <L> deleteOperation)
     where T : Entity
     where L : Entity
 {
     return(fi.WithVirtualMList(mListField, backReference,
                                onSave: saveOperation == null ? null : new Action <L, T>((line, e) =>
     {
         line.Execute(saveOperation);
     }),
                                onRemove: deleteOperation == null ? null : new Action <L, T>((line, e) =>
     {
         line.Delete(deleteOperation);
     })));
 }
Esempio n. 15
0
        public static FluentInclude <T> WithDeletePart <T, L>(this FluentInclude <T> fi, Expression <Func <T, L> > relatedEntity)
            where T : Entity
            where L : Entity
        {
            fi.SchemaBuilder.Schema.EntityEvents <T>().PreUnsafeDelete += query =>
            {
                if (ShouldAvoidDeletePart(typeof(L)))
                {
                    return(null);
                }

                var toDelete = query.Select(relatedEntity).Select(a => a.ToLite()).ToList().NotNull().Distinct().ToList();
                return(new Disposable(() =>
                {
                    var groups = toDelete.GroupsOf(Connector.Current.Schema.Settings.MaxNumberOfParameters).ToList();
                    groups.ForEach(l => Database.DeleteList(l));
                }));
            };
            return(fi);
        }
Esempio n. 16
0
 public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                         Func <T, MList <L> > getMList,
                                                         Expression <Func <L, Lite <T> > > getBackReference,
                                                         ExecuteSymbol <L> saveOperation,
                                                         DeleteSymbol <L> deleteOperation)
     where T : Entity
     where L : Entity
 {
     return(fi.WithVirtualMList(getMList, getBackReference,
                                onSave: saveOperation == null ? null : new Action <L, T>((line, e) =>
     {
         if (line.IsGraphModified)
         {
             line.Execute(saveOperation);
         }
     }),
                                onRemove: deleteOperation == null ? null : new Action <L, T>((line, e) =>
     {
         line.Delete(deleteOperation);
     })));
 }
Esempio n. 17
0
    public static FluentInclude <T> WithDeletePart <T, L>(this FluentInclude <T> fi, Expression <Func <T, L> > relatedEntity, Expression <Func <T, bool> >?filter = null, Func <T, bool>?handleOnSaving = null)
        where T : Entity
        where L : Entity
    {
        fi.SchemaBuilder.Schema.EntityEvents <T>().PreUnsafeDelete += query =>
        {
            if (ShouldAvoidDeletePart(typeof(L)))
            {
                return(null);
            }

            var filteredQuery = filter == null ? query : query.Where(filter);

            var toDelete = filteredQuery.Select(relatedEntity).Select(a => a.ToLite()).ToList().NotNull().Distinct().ToList();
            return(new Disposable(() =>
            {
                var groups = toDelete.Chunk(Connector.Current.Schema.Settings.MaxNumberOfParameters).ToList();
                groups.ForEach(l => Database.DeleteList(l));
            }));
        };
        if (handleOnSaving != null)
        {
            fi.SchemaBuilder.Schema.EntityEvents <T>().Saving += e =>
            {
                if (!e.IsNew && handleOnSaving !(e))
                {
                    var lite = e.InDB().Select(relatedEntity).Select(a => a.ToLite()).SingleEx();
                    if (!lite.Is(relatedEntity.Evaluate(e)))
                    {
                        Transaction.PreRealCommit += dic =>
                        {
                            lite.Delete();
                        };
                    }
                }
            }
        }
        ;
        return(fi);
    }
Esempio n. 18
0
        public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                                Expression <Func <T, MList <L> > > mListField,
                                                                Expression <Func <L, Lite <T>?> > backReference,
                                                                Action <L, T>?onSave   = null,
                                                                Action <L, T>?onRemove = null,
                                                                bool?lazyRetrieve      = null,
                                                                bool?lazyDelete        = null) //To avoid StackOverflows
            where T : Entity
            where L : Entity
        {
            fi.SchemaBuilder.Include <L>();

            var mListPropertRoute  = PropertyRoute.Construct(mListField);
            var backReferenceRoute = PropertyRoute.Construct(backReference, avoidLastCasting: true);

            if (fi.SchemaBuilder.Settings.FieldAttribute <IgnoreAttribute>(mListPropertRoute) == null)
            {
                throw new InvalidOperationException($"The property {mListPropertRoute} should have an IgnoreAttribute to be used as Virtual MList");
            }

            RegisteredVirtualMLists.GetOrCreate(typeof(T)).Add(mListPropertRoute, new VirtualMListInfo(mListPropertRoute, backReferenceRoute));

            var defLazyRetrieve = lazyRetrieve ?? (typeof(L) == typeof(T));
            var defLazyDelete   = lazyDelete ?? (typeof(L) == typeof(T));

            Func <T, MList <L> >  getMList = GetAccessor(mListField);
            Action <L, Lite <T> >?setter   = null;
            bool preserveOrder             = fi.SchemaBuilder.Settings.FieldAttributes(mListPropertRoute) !
                                             .OfType <PreserveOrderAttribute>()
                                             .Any();

            if (preserveOrder && !typeof(ICanBeOrdered).IsAssignableFrom(typeof(L)))
            {
                throw new InvalidOperationException($"'{typeof(L).Name}' should implement '{nameof(ICanBeOrdered)}' because '{ReflectionTools.GetPropertyInfo(mListField).Name}' contains '[{nameof(PreserveOrderAttribute)}]'");
            }

            var sb = fi.SchemaBuilder;

            if (defLazyRetrieve)
            {
                sb.Schema.EntityEvents <T>().Retrieved += (T e, PostRetrievingContext ctx) =>
                {
                    if (ShouldAvoidMListType(typeof(L)))
                    {
                        return;
                    }

                    var mlist = getMList(e);

                    if (mlist == null)
                    {
                        return;
                    }

                    var query = Database.Query <L>()
                                .Where(line => backReference.Evaluate(line) == e.ToLite());

                    MList <L> newList = preserveOrder ?
                                        query.ToVirtualMListWithOrder() :
                                        query.ToVirtualMList();

                    mlist.AssignAndPostRetrieving(newList, ctx);
                };
            }

            if (preserveOrder)
            {
                sb.Schema.EntityEvents <T>().RegisterBinding <MList <L> >(mListField,
                                                                          shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)),
                                                                          valueExpression: (e, rowId) => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder(),
                                                                          valueFunction: (e, rowId, retriever) => Schema.Current.CacheController <L>() !.Enabled ?
                                                                          Schema.Current.CacheController <L>() !.RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder():
                                                                          Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder()

                                                                          );
            }
            else
            {
                sb.Schema.EntityEvents <T>().RegisterBinding(mListField,
                                                             shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)),
                                                             valueExpression: (e, rowId) => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList(),
                                                             valueFunction: (e, rowId, retriever) => Schema.Current.CacheController <L>() !.Enabled ?
                                                             Schema.Current.CacheController <L>() !.RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMList() :
                                                             Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList()
                                                             );
            }

            sb.Schema.EntityEvents <T>().PreSaving += (T e, PreSavingContext ctx) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);
                if (mlist == null)
                {
                    return;
                }

                if (mlist.Count > 0)
                {
                    var graph = Saver.PreSaving(() => GraphExplorer.FromRoot(mlist).RemoveAllNodes(ctx.Graph));
                    GraphExplorer.PropagateModifications(graph.Inverse());
                    var errors = GraphExplorer.FullIntegrityCheck(graph);
                    if (errors != null)
                    {
#if DEBUG
                        var withEntites = errors.WithEntities(graph);
                        throw new IntegrityCheckException(withEntites);
#else
                        throw new IntegrityCheckException(errors);
#endif
                    }
                }

                if (mlist.IsGraphModified)
                {
                    e.SetSelfModified();
                }
            };

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);
                if (mlist == null)
                {
                    return;
                }

                if (preserveOrder)
                {
                    mlist.ForEach((o, i) => ((ICanBeOrdered)o).Order = i);
                }

                if (GraphExplorer.IsGraphModified(mlist))
                {
                    e.SetModified();
                }
            };
            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);

                if (mlist != null && !GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (!(args.WasNew || ShouldConsiderNew(typeof(T))))
                {
                    var oldElements = mlist.EmptyIfNull().Where(line => !line.IsNew);
                    var query       = Database.Query <L>()
                                      .Where(p => backReference.Evaluate(p) == e.ToLite());

                    if (onRemove == null)
                    {
                        query.Where(p => !oldElements.Contains(p)).UnsafeDelete();
                    }
                    else
                    {
                        query.Where(p => !oldElements.Contains(p)).ToList().ForEach(line => onRemove !(line, e));
                    }
                }

                if (mlist != null)
                {
                    if (mlist.Any())
                    {
                        if (setter == null)
                        {
                            setter = CreateSetter(backReference);
                        }

                        mlist.ForEach(line => setter !(line, e.ToLite()));
                        if (onSave == null)
                        {
                            mlist.SaveList();
                        }
                        else
                        {
                            mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line))
                                                    {
                                                        onSave !(line, e);
                                                    }
                                          });
                        }

                        var priv = (IMListPrivate)mlist;
                        for (int i = 0; i < mlist.Count; i++)
                        {
                            if (priv.GetRowId(i) == null)
                            {
                                priv.SetRowId(i, mlist[i].Id);
                            }
                        }
                    }
                    mlist.SetCleanModified(false);
                }
            };


            sb.Schema.EntityEvents <T>().PreUnsafeDelete += query =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return(null);
                }

                //You can do a VirtualMList to itself at the table level, but there should not be cycles inside the instances
                var toDelete = Database.Query <L>().Where(se => query.Any(e => backReference.Evaluate(se).Is(e)));
                if (defLazyDelete)
                {
                    if (toDelete.Any())
                    {
                        toDelete.UnsafeDelete();
                    }
                }
                else
                {
                    toDelete.UnsafeDelete();
                }
                return(null);
            };

            return(fi);
        }
 public static FluentInclude <T> WithQuery <T, Q>(this FluentInclude <T> fi, DynamicQueryManager dqm, Func <DynamicQueryCore <Q> > lazyGetQuery)
     where T : Entity
 {
     dqm.RegisterQuery <Q>(typeof(T), () => lazyGetQuery());
     return(fi);
 }
Esempio n. 20
0
        public static FluentInclude <T> WithVirtualMListInitializeOnly <T, L>(this FluentInclude <T> fi,
                                                                              Expression <Func <T, MList <L> > > mListField,
                                                                              Expression <Func <L, Lite <T>?> > backReference,
                                                                              Action <L, T>?onSave = null)
            where T : Entity
            where L : Entity
        {
            fi.SchemaBuilder.Include <L>();

            Func <T, MList <L> >  getMList = GetAccessor(mListField);
            Action <L, Lite <T> >?setter   = null;
            var sb = fi.SchemaBuilder;

            sb.Schema.EntityEvents <T>().RegisterBinding(mListField,
                                                         shouldSet: () => false,
                                                         valueExpression: (e, rowId) => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder()
                                                         );

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);
                if (mlist == null)
                {
                    return;
                }

                if (GraphExplorer.IsGraphModified(getMList(e)))
                {
                    e.SetModified();
                }
            };

            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);
                if (mlist == null)
                {
                    return;
                }

                if (!GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (setter == null)
                {
                    setter = CreateSetter(backReference);
                }

                mlist.ForEach(line => setter !(line, e.ToLite()));
                if (onSave == null)
                {
                    mlist.SaveList();
                }
                else
                {
                    mlist.ForEach(line =>
                    {
                        if (GraphExplorer.IsGraphModified(line))
                        {
                            onSave !(line, e);
                        }
                    });
                }
                var priv = (IMListPrivate)mlist;
                for (int i = 0; i < mlist.Count; i++)
                {
                    if (priv.GetRowId(i) == null)
                    {
                        priv.SetRowId(i, mlist[i].Id);
                    }
                }
                mlist.SetCleanModified(false);
            };
            return(fi);
        }
Esempio n. 21
0
 /// <summary>
 /// Uses NicePluralName as niceName
 /// </summary>
 public static FluentInclude <T> WithExpressionFrom <T, F>(this FluentInclude <T> fi, DynamicQueryManager dqm, Expression <Func <F, IQueryable <T> > > lambdaToMethodOrProperty)
     where T : Entity
 {
     dqm.RegisterExpression(lambdaToMethodOrProperty, () => typeof(T).NicePluralName());
     return(fi);
 }
Esempio n. 22
0
        public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                                Expression <Func <T, MList <L> > > mListField,
                                                                Expression <Func <L, Lite <T> > > getBackReference,
                                                                Action <L, T> onSave   = null,
                                                                Action <L, T> onRemove = null)
            where T : Entity
            where L : Entity
        {
            Func <T, MList <L> >  getMList = mListField.Compile();
            Action <L, Lite <T> > setter   = null;
            bool preserveOrder             = fi.SchemaBuilder.Settings.FieldAttributes(mListField)
                                             .OfType <PreserveOrderAttribute>()
                                             .Any();
            var sb = fi.SchemaBuilder;

            sb.Schema.EntityEvents <T>().Retrieved += (T e) =>
            {
                var mlist = getMList(e);

                List <L> list = Database.Query <L>()
                                .Where(line => getBackReference.Evaluate(line) == e.ToLite())
                                .ToList();
                if (preserveOrder)
                {
                    list = list.OrderBy(le => ((ICanBeOrdered)le).Order).ToList();
                }

                var rowIdElements = list
                                    .Select(line => new MList <L> .RowIdElement(line, line.Id, null));

                ((IMListPrivate <L>)mlist).InnerList.AddRange(rowIdElements);
            };

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                var mlist = getMList(e);
                if (preserveOrder)
                {
                    mlist.ForEach((o, i) => ((ICanBeOrdered)o).Order = i);
                }

                if (GraphExplorer.IsGraphModified(mlist))
                {
                    e.SetModified();
                }
            };
            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                var mlist = getMList(e);

                if (!GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (!args.WasNew)
                {
                    var oldElements = mlist.Where(line => !line.IsNew);
                    var query       = Database.Query <L>()
                                      .Where(p => getBackReference.Evaluate(p) == e.ToLite());

                    if (onRemove == null)
                    {
                        query.Where(p => !oldElements.Contains(p)).UnsafeDelete();
                    }
                    else
                    {
                        query.ToList().ForEach(line => onRemove(line, e));
                    }
                }

                if (setter == null)
                {
                    setter = CreateSetter(getBackReference);
                }

                mlist.ForEach(line => setter(line, e.ToLite()));
                if (onSave == null)
                {
                    mlist.SaveList();
                }
                else
                {
                    mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line))
                                            {
                                                onSave(line, e);
                                            }
                                  });
                }
                var priv = (IMListPrivate)mlist;
                for (int i = 0; i < mlist.Count; i++)
                {
                    if (priv.GetRowId(i) == null)
                    {
                        priv.SetRowId(i, mlist[i].Id);
                    }
                }
                mlist.SetCleanModified(false);
            };

            sb.Schema.EntityEvents <T>().PreUnsafeDelete += query => query.SelectMany(e => Database.Query <L>().Where(se => getBackReference.Evaluate(se).RefersTo(e))).UnsafeDelete();

            return(fi);
        }
Esempio n. 23
0
 public static FluentInclude <T> WithQuery <T, Q>(this FluentInclude <T> fi, DynamicQueryManager dqm, Expression <Func <T, Q> > simpleQuerySelector)
     where T : Entity
 {
     dqm.RegisterQuery <Q>(typeof(T), () => Database.Query <T>().Select(simpleQuerySelector));
     return(fi);
 }
 public static FluentInclude <T> WithQuery <T, Q>(this FluentInclude <T> fi, Func <DynamicQueryCore <Q> > lazyGetQuery)
     where T : Entity
 {
     QueryLogic.Queries.Register <Q>(typeof(T), () => lazyGetQuery());
     return(fi);
 }
Esempio n. 25
0
        public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                                Expression <Func <T, MList <L> > > mListField,
                                                                Expression <Func <L, Lite <T> > > backReference,
                                                                Action <L, T> onSave       = null,
                                                                Action <L, T> onRemove     = null,
                                                                bool?lazyRetrieveAndDelete = null) //To avoid StackOverflows
            where T : Entity
            where L : Entity
        {
            RegisteredVirtualMLists.GetOrCreate(typeof(T)).Add(typeof(L));

            var lazy = lazyRetrieveAndDelete ?? (typeof(L) == typeof(T));

            Func <T, MList <L> >  getMList = GetAccessor(mListField);
            Action <L, Lite <T> > setter   = null;
            bool preserveOrder             = fi.SchemaBuilder.Settings.FieldAttributes(mListField)
                                             .OfType <PreserveOrderAttribute>()
                                             .Any();

            if (preserveOrder && !typeof(ICanBeOrdered).IsAssignableFrom(typeof(L)))
            {
                throw new InvalidOperationException($"'{typeof(L).Name}' should implement '{nameof(ICanBeOrdered)}' because '{ReflectionTools.GetPropertyInfo(mListField).Name}' contains '[{nameof(PreserveOrderAttribute)}]'");
            }

            var sb = fi.SchemaBuilder;

            if (lazy)
            {
                sb.Schema.EntityEvents <T>().Retrieved += (T e) =>
                {
                    if (ShouldAvoidMListType(typeof(L)))
                    {
                        return;
                    }

                    var mlist = getMList(e);

                    if (mlist == null)
                    {
                        return;
                    }

                    var query = Database.Query <L>()
                                .Where(line => backReference.Evaluate(line) == e.ToLite());

                    MList <L> newList = preserveOrder ?
                                        query.ToVirtualMListWithOrder() :
                                        query.ToVirtualMList();

                    mlist.AssignAndPostRetrieving(newList);
                };
            }

            if (preserveOrder)
            {
                sb.Schema.EntityEvents <T>().RegisterBinding <MList <L> >(mListField,
                                                                          shouldSet: () => !lazy && !VirtualMList.ShouldAvoidMListType(typeof(L)),
                                                                          valueExpression: e => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder(),
                                                                          valueFunction: (e, retriever) => Schema.Current.CacheController <L>().RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder()
                                                                          );
            }
            else
            {
                sb.Schema.EntityEvents <T>().RegisterBinding(mListField,
                                                             shouldSet: () => !lazy && !VirtualMList.ShouldAvoidMListType(typeof(L)),
                                                             valueExpression: e => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList(),
                                                             valueFunction: (e, retriever) => Schema.Current.CacheController <L>().RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMList()
                                                             );
            }

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);
                if (mlist == null)
                {
                    return;
                }

                if (preserveOrder)
                {
                    mlist.ForEach((o, i) => ((ICanBeOrdered)o).Order = i);
                }

                if (GraphExplorer.IsGraphModified(mlist))
                {
                    e.SetModified();
                }
            };
            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return;
                }

                var mlist = getMList(e);

                if (mlist != null && !GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (!(args.WasNew || ShouldConsiderNew(typeof(T))))
                {
                    var oldElements = mlist.EmptyIfNull().Where(line => !line.IsNew);
                    var query       = Database.Query <L>()
                                      .Where(p => backReference.Evaluate(p) == e.ToLite());

                    if (onRemove == null)
                    {
                        query.Where(p => !oldElements.Contains(p)).UnsafeDelete();
                    }
                    else
                    {
                        query.ToList().ForEach(line => onRemove(line, e));
                    }
                }

                if (mlist != null)
                {
                    if (setter == null)
                    {
                        setter = CreateSetter(backReference);
                    }

                    mlist.ForEach(line => setter(line, e.ToLite()));
                    if (onSave == null)
                    {
                        mlist.SaveList();
                    }
                    else
                    {
                        mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line))
                                                {
                                                    onSave(line, e);
                                                }
                                      });
                    }
                    var priv = (IMListPrivate)mlist;
                    for (int i = 0; i < mlist.Count; i++)
                    {
                        if (priv.GetRowId(i) == null)
                        {
                            priv.SetRowId(i, mlist[i].Id);
                        }
                    }
                    mlist.SetCleanModified(false);
                }
            };


            sb.Schema.EntityEvents <T>().PreUnsafeDelete += query =>
            {
                if (VirtualMList.ShouldAvoidMListType(typeof(L)))
                {
                    return(null);
                }

                //You can do a VirtualMList to itself at the table level, but there should not be cycles inside the instances
                var toDelete = Database.Query <L>().Where(se => query.Any(e => backReference.Evaluate(se).RefersTo(e)));
                if (lazy)
                {
                    if (toDelete.Any())
                    {
                        toDelete.UnsafeDelete();
                    }
                }
                else
                {
                    toDelete.UnsafeDelete();
                }
                return(null);
            };

            return(fi);
        }
 /// <summary>
 /// Uses typeof(T) NicePluralName as niceName
 /// </summary>
 public static FluentInclude <T> WithExpressionFrom <T, F>(this FluentInclude <T> fi, Expression <Func <F, IQueryable <T> > > lambdaToMethodOrProperty)
     where T : Entity
 {
     QueryLogic.Expressions.Register(lambdaToMethodOrProperty, () => typeof(T).NicePluralName());
     return(fi);
 }
 public static FluentInclude <T> WithExpressionFrom <T, F>(this FluentInclude <T> fi, Expression <Func <F, IQueryable <T> > > lambdaToMethodOrProperty, Func <string> niceName)
     where T : Entity
 {
     QueryLogic.Expressions.Register(lambdaToMethodOrProperty, niceName);
     return(fi);
 }
 //public static FluentInclude<T> WithQuery<T, A>(this FluentInclude<T> fi, Func<Expression<Func<T, A>>> lazyQuerySelector)  <-- C# Generic argument inference not so smart as to do this
 public static FluentInclude <T> WithQuery <T>(this FluentInclude <T> fi, Func <Expression <Func <T, object?> > > lazyQuerySelector)
     where T : Entity
 {
     QueryLogic.Queries.Register(typeof(T), new DynamicQueryBucket(typeof(T), () => DynamicQueryCore.FromSelectorUntyped(lazyQuerySelector()), Implementations.By(typeof(T))));
     return(fi);
 }
Esempio n. 29
0
 public static FluentInclude <T> WithCache <T>(this FluentInclude <T> fi)
     where T : Entity
 {
     CacheLogic.TryCacheTable(fi.SchemaBuilder, typeof(T));
     return(fi);
 }
Esempio n. 30
0
        public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi,
                                                                Func <T, MList <L> > getMList,
                                                                Expression <Func <L, Lite <T> > > getBackReference,
                                                                Action <L, T> onSave   = null,
                                                                Action <L, T> onRemove = null)
            where T : Entity
            where L : Entity
        {
            Action <L, Lite <T> > setter = null;
            var sb = fi.SchemaBuilder;

            sb.Schema.EntityEvents <T>().Retrieved += (T e) =>
            {
                var mlist = getMList(e);

                var rowIdElements = Database.Query <L>()
                                    .Where(line => getBackReference.Evaluate(line) == e.ToLite())
                                    .ToList()
                                    .Select(line => new MList <L> .RowIdElement(line, line.Id, null));

                ((IMListPrivate <L>)mlist).InnerList.AddRange(rowIdElements);
            };

            sb.Schema.EntityEvents <T>().Saving += (T e) =>
            {
                if (GraphExplorer.IsGraphModified(getMList(e)))
                {
                    e.SetModified();
                }
            };
            sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) =>
            {
                var mlist = getMList(e);

                if (!GraphExplorer.IsGraphModified(mlist))
                {
                    return;
                }

                if (!args.WasNew)
                {
                    var oldElements = mlist.Where(line => !line.IsNew);
                    var query       = Database.Query <L>()
                                      .Where(p => getBackReference.Evaluate(p) == e.ToLite());

                    if (onRemove == null)
                    {
                        query.Where(p => !oldElements.Contains(p)).UnsafeDelete();
                    }
                    else
                    {
                        query.ToList().ForEach(line => onRemove(line, e));
                    }
                }

                if (setter == null)
                {
                    setter = CreateGetter(getBackReference);
                }

                mlist.ForEach(line => setter(line, e.ToLite()));
                if (onSave == null)
                {
                    mlist.SaveList();
                }
                else
                {
                    mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line))
                                            {
                                                onSave(line, e);
                                            }
                                  });
                }
                var priv = (IMListPrivate)mlist;
                for (int i = 0; i < mlist.Count; i++)
                {
                    if (priv.GetRowId(i) == null)
                    {
                        priv.SetRowId(i, mlist[i].Id);
                    }
                }
                mlist.SetCleanModified(false);
            };

            return(fi);
        }