public virtual async Task <EntityPackage> WriteViewBaseAsync(V view, Requester requester, Action <EntityPackage> modifyBeforeCreate = null) //, bool history = true)
        {
            logger.LogTrace("WriteViewAsync called");

            var sem = entityLocks.GetOrAdd(view.id, i => new SemaphoreSlim(1, 1));

            await sem.WaitAsync();

            try
            {
                EntityPackage existing = null;

                view = await CleanViewGeneralAsync(view, requester);

                if (view.id != 0)
                {
                    existing = await provider.FindByIdAsync(view.id);

                    view = await CleanViewUpdateAsync(view, existing, requester);
                }

                //Now that the view they gave is all clean, do the full conversion! It should be safe!
                var package = converter.FromView(view);

                //If this is an UPDATE, do some STUFF
                if (view.id != 0)
                {
                    await services.history.UpdateWithHistoryAsync(package, requester.userId, existing);
                }
                else
                {
                    await services.history.InsertWithHistoryAsync(package, requester.userId, modifyBeforeCreate);
                }

                return(package);
            }
            finally
            {
                sem.Release();
            }
        }
        //public async Task<EntityPackage> UpdateFieldsNoHistory(Requester requester, Action<)

        public virtual async Task <EntityPackage> WriteViewBaseAsync(V view, Requester requester, Action <EntityPackage> modifyBeforeCreate = null) //, bool history = true)
        {
            logger.LogTrace("WriteViewAsync called");

            var sem = entityLocks.GetOrAdd(view.id, i => new SemaphoreSlim(1, 1));

            await sem.WaitAsync();

            try
            {
                EntityPackage existing = null;

                view = await CleanViewGeneralAsync(view, requester);

                if (view.id != 0)
                {
                    existing = await provider.FindByIdAsync(view.id);

                    view = await CleanViewUpdateAsync(view, existing, requester);
                }

                //Now that the view they gave is all clean, do the full conversion! It should be safe!
                var package = converter.FromView(view);

                //Only historic writes (default) do fancy stuff.
                //if(history)
                //{
                //If this is an UPDATE, do some STUFF
                if (view.id != 0)
                {
                    await services.history.UpdateWithHistoryAsync(package, requester.userId, existing);
                }
                else
                {
                    await services.history.InsertWithHistoryAsync(package, requester.userId, modifyBeforeCreate);
                }
                //}
                //else
                //{
                //    var deletes = new List<EntityBase>();

                //    //Go find all the OLD values and relations and DELETE them?? deleting seems scary idk...
                //    if(existing != null)
                //    {
                //        existing.Relations.ForEach(x => x.type = "XXX");
                //        existing.Values.ForEach(x => x.key = "XXX");

                //        deletes.AddRange(existing.Relations);
                //        deletes.AddRange(existing.Values);
                //    }

                //    //This NEEDS TO BE RETRIED IF SOMETHING FAILS!!!!
                //    if(deletes.Count > 0)
                //        await BadStaticCrap.BasicRetry(() => services.provider.WriteAsync(deletes.ToArray()));

                //    //var oldRelations = services.provider.GetEntityRelationsAsync(new EntityRelationSearch() { Ent})
                //    await services.provider.WriteAsync(package);

                //    //This NEEDS TO BE RETRIED IF SOMETHING FAILS!!!!
                //    if(deletes.Count > 0)
                //        await BadStaticCrap.BasicRetry(() => services.provider.DeleteAsync(deletes.ToArray()));
                //}

                return(package);
            }
            finally
            {
                sem.Release();
            }
        }