示例#1
0
        protected IEnumerable <Row> CreateRows(DbSetInfo dbSetInfo, IEnumerable <object> dataSource, int rowCount)
        {
            var fields    = dbSetInfo.fieldInfos.Where(f => f.isIncludeInResult()).OrderBy(f => f._ordinal).ToArray();
            int fieldsCnt = fields.Length;

            FieldInfo[] pkInfos = dbSetInfo.GetPKFieldInfos();
            Row[]       rows    = new Row[rowCount];

            int counter = 0;

            foreach (object entity in dataSource)
            {
                Row      row = new Row();
                string[] pk  = new string[pkInfos.Length];
                row.values = new string[fieldsCnt];
                for (int i = 0; i < fieldsCnt; ++i)
                {
                    string    fv  = null;
                    FieldInfo fld = fields[i];

                    fv = this.DataHelper.GetFieldValueAsString(entity, fld.fieldName);

                    int keyIndex = Array.IndexOf(pkInfos, fld);
                    if (keyIndex > -1)
                    {
                        pk[keyIndex] = fv;
                    }
                    row.values[i] = fv;
                }
                row.key       = string.Join(";", pk);
                rows[counter] = row;
                ++counter;
            }
            return(rows);
        }
示例#2
0
        protected void UpdateRowInfoAfterUpdates(RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;
            var       fields    = dbSetInfo.GetFieldByNames();

            rowInfo.values.ForEach((fv) =>
            {
                FieldInfo finfo = fields[fv.fieldName];
                if (!finfo.isIncludeInResult())
                {
                    return;
                }
                string newVal;
                if (this.isEntityValueChanged(rowInfo, finfo.fieldName, out newVal))
                {
                    fv.val   = newVal;
                    fv.flags = fv.flags | ValueFlags.Refreshed;
                }
            });

            if (rowInfo.changeType == ChangeType.Added)
            {
                rowInfo.serverKey = rowInfo.GetRowKeyAsString();
            }
        }
示例#3
0
 public string GetRowKeyAsString(DbSetInfo dbSetInfo)
 {
     FieldInfo[] finfos = DataHelper.GetPKFieldInfos(dbSetInfo);
     string[]    vals   = new string[finfos.Length];
     for (int i = 0; i < finfos.Length; ++i)
     {
         ValueChange fv = this.GetValue(finfos[i].fieldName);
         vals[i] = fv.val;
     }
     return(string.Join(";", vals));
 }
示例#4
0
        public object GetTypedValue(Type entityType, DbSetInfo dbSetInfo)
        {
            FieldInfo    fi    = dbSetInfo.GetFieldByNames()[this.fieldName];
            PropertyInfo pinfo = entityType.GetProperty(fi.fieldName);

            if (pinfo == null)
            {
                throw new Exception(string.Format(ErrorStrings.ERR_PROPERTY_IS_MISSING, entityType.Name, fi.fieldName));
            }

            Type propType = pinfo.PropertyType;

            return(DataHelper.ConvertToTyped(propType, fi.dataType, fi.dateConversion, this.val));
        }
示例#5
0
        protected IEnumerable <IncludedResult> CreateIncludedResults(DbSetInfo dbSetInfo, IEnumerable <object> entities, string[] includePaths)
        {
            if (includePaths.Length == 0)
            {
                return(Enumerable.Empty <IncludedResult>());
            }
            Dictionary <string, IncludedResult> visited = new Dictionary <string, IncludedResult>();
            var metadata = this.EnsureMetadataInitialized();

            foreach (string includePath in includePaths)
            {
                string[] pathParts = includePath.Split('.');
                string[] nextParts = pathParts.Skip(1).ToArray();
                this.CreateIncludedResult(dbSetInfo, entities, pathParts[0], nextParts, visited);
            }
            return(visited.Values);
        }
示例#6
0
        protected virtual void AuthorizeChangeSet(ChangeSet changeSet)
        {
            try
            {
                var metadata = this.EnsureMetadataInitialized();
                foreach (var dbSet in changeSet.dbSets)
                {
                    //methods on domain service which are attempted to be executed by client (SaveChanges triggers their execution)
                    Dictionary <string, MethodInfo> domainServiceMethods = new Dictionary <string, MethodInfo>();
                    DbSetInfo dbInfo = metadata.dbSets[dbSet.dbSetName];
                    this._currentDbSet = dbSet;

                    foreach (RowInfo rowInfo in dbSet.rows)
                    {
                        this._currentRowInfo = rowInfo;
                        MethodInfo methInfo = null;
                        try
                        {
                            methInfo = SecurityHelper.GetCRUDMethodInfo(dbInfo, rowInfo);
                        }
                        finally
                        {
                            this._currentRowInfo = null;
                        }

                        if (methInfo == null)
                        {
                            throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbInfo.EntityType.Name, rowInfo.changeType));
                        }

                        if (!domainServiceMethods.ContainsKey(methInfo.Name))
                        {
                            domainServiceMethods.Add(methInfo.Name, methInfo);
                        }
                    } // foreach (RowInfo rowInfo in dbSet.rows)

                    this.Authorizer.CheckUserRightsToExecute(domainServiceMethods.Values.ToArray());
                } //foreach (var dbSet in changeSet.dbSets)
            }
            finally
            {
                this._currentDbSet = null;
            }
        }
示例#7
0
        public void Prepare()
        {
            var rowsMap = this.GetRowsMap();

            foreach (var trackAssoc in changeSet.trackAssocs)
            {
                var             assoc     = this._metadata.associations[trackAssoc.assocName];
                string          pkey      = string.Format("{0}:{1}", assoc.parentDbSetName, trackAssoc.parentKey);
                string          ckey      = string.Format("{0}:{1}", assoc.childDbSetName, trackAssoc.childKey);
                RowInfo         parent    = rowsMap[pkey];
                RowInfo         child     = rowsMap[ckey];
                ParentChildNode childNode = new ParentChildNode(child);
                childNode.association = assoc;
                childNode.ParentRow   = parent;
                updateNodes.AddLast(childNode);
            }


            foreach (var dbSet in this.GetSortedDbSets())
            {
                foreach (RowInfo rowInfo in dbSet.rows)
                {
                    DbSetInfo dbSetInfo = rowInfo.dbSetInfo;
                    _allList.AddLast(rowInfo);
                    switch (rowInfo.changeType)
                    {
                    case ChangeType.Added:
                        _insertList.AddLast(rowInfo);
                        break;

                    case ChangeType.Deleted:
                        _insertList.AddFirst(rowInfo);
                        break;

                    case ChangeType.Updated:
                        _updateList.AddLast(rowInfo);
                        break;

                    default:
                        throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbSetInfo.EntityType.Name, rowInfo.changeType));
                    }
                }
            }
        }
示例#8
0
        protected void InsertEntity(RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;

            if (rowInfo.changeType != ChangeType.Added)
            {
                throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbSetInfo.EntityType.Name, rowInfo.changeType));
            }
            MethodInfo methInfo = this.GetOperMethodInfo(dbSetInfo, OperationNames.CREATE);

            if (methInfo == null)
            {
                throw new DomainServiceException(string.Format(ErrorStrings.ERR_DB_INSERT_NOT_IMPLEMENTED, dbSetInfo.EntityType.Name, this.GetType().Name));
            }
            object dbEntity = Activator.CreateInstance(dbSetInfo.EntityType);

            UpdateEntityFromRowInfo(dbEntity, rowInfo, false);
            rowInfo.changeState.Entity = dbEntity;
            methInfo.Invoke(this, new object[] { dbEntity });
        }
示例#9
0
        private Dictionary <string, RowInfo> GetRowsMap()
        {
            Dictionary <string, RowInfo> result = new Dictionary <string, RowInfo>();

            foreach (var dbSet in changeSet.dbSets)
            {
                DbSetInfo dbSetInfo = this._metadata.dbSets[dbSet.dbSetName];
                if (dbSetInfo.EntityType == null)
                {
                    throw new DomainServiceException(string.Format(ErrorStrings.ERR_DB_ENTITYTYPE_INVALID, dbSetInfo.dbSetName));
                }

                foreach (RowInfo rowInfo in dbSet.rows)
                {
                    rowInfo.dbSetInfo = dbSetInfo;
                    result.Add(GetKey(rowInfo), rowInfo);
                }
            }
            return(result);
        }
示例#10
0
        protected void UpdateRowInfoFromEntity(object entity, RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;
            var       values    = rowInfo.values;
            var       fields    = dbSetInfo.GetFieldByNames();

            values.ForEach((fv) =>
            {
                FieldInfo finfo = fields[fv.fieldName];
                if (!finfo.isIncludeInResult())
                {
                    return;
                }
                fv.val   = this.DataHelper.GetFieldValueAsString(entity, finfo.fieldName);
                fv.flags = fv.flags | ValueFlags.Refreshed;
            });

            if (rowInfo.changeType == ChangeType.Added)
            {
                rowInfo.serverKey = rowInfo.GetRowKeyAsString();
            }
        }
示例#11
0
        protected virtual void ApplyChangesToEntity(RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;

            if (dbSetInfo.EntityType == null)
            {
                throw new DomainServiceException(string.Format(ErrorStrings.ERR_DB_ENTITYTYPE_INVALID, dbSetInfo.dbSetName));
            }
            try
            {
                switch (rowInfo.changeType)
                {
                case ChangeType.Added:
                    this.InsertEntity(rowInfo);
                    break;

                case ChangeType.Deleted:
                    this.DeleteEntity(rowInfo);
                    break;

                case ChangeType.Updated:
                    this.UpdateEntity(rowInfo);
                    break;

                default:
                    throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbSetInfo.EntityType.Name, rowInfo.changeType));
                }
            }
            catch (Exception ex)
            {
                object dbEntity = rowInfo.changeState == null ? null : rowInfo.changeState.Entity;
                rowInfo.changeState = new EntityChangeState {
                    Entity = dbEntity, Error = ex
                };
                this.OnError(ex);
                throw;
            }
        }
示例#12
0
        protected void UpdateEntity(RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;

            if (rowInfo.changeType != ChangeType.Updated)
            {
                throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbSetInfo.EntityType.Name, rowInfo.changeType));
            }
            MethodInfo methInfo = this.GetOperMethodInfo(dbSetInfo, OperationNames.UPDATE);

            if (methInfo == null)
            {
                throw new DomainServiceException(string.Format(ErrorStrings.ERR_DB_UPDATE_NOT_IMPLEMENTED, dbSetInfo.EntityType.Name, this.GetType().Name));
            }
            object dbEntity = Activator.CreateInstance(dbSetInfo.EntityType);

            UpdateEntityFromRowInfo(dbEntity, this._currentRowInfo, false);
            var original = this.GetOriginal(dbEntity);

            rowInfo.changeState.Entity         = dbEntity;
            rowInfo.changeState.OriginalEntity = original;
            //apply this changes to entity that is in the database (this is done in user domain service method)
            methInfo.Invoke(this, new object[] { dbEntity });
        }
示例#13
0
        protected bool ValidateEntity(RowInfo rowInfo)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;
            IEnumerable <ValidationErrorInfo> errs = null;
            LinkedList <string> mustBeChecked      = new LinkedList <string>();
            LinkedList <string> skipCheckList      = null;

            if (rowInfo.changeType == ChangeType.Added)
            {
                skipCheckList = new LinkedList <string>();
                foreach (var pn in rowInfo.changeState.ParentRows)
                {
                    foreach (var frel in pn.association.fieldRels)
                    {
                        skipCheckList.AddLast(frel.childField);
                    }
                }
            }

            foreach (var fieldInfo in dbSetInfo.fieldInfos)
            {
                if (!fieldInfo.isIncludeInResult())
                {
                    continue;
                }
                string value = this.DataHelper.GetFieldValueAsString(rowInfo.changeState.Entity, fieldInfo.fieldName);
                if (rowInfo.changeType == ChangeType.Added)
                {
                    bool isSkip = fieldInfo.isAutoGenerated || (skipCheckList != null && skipCheckList.Any(n => n == fieldInfo.fieldName));
                    if (!isSkip)
                    {
                        this.ValidationHelper.CheckValue(fieldInfo, value);
                        mustBeChecked.AddLast(fieldInfo.fieldName);
                    }
                }
                else if (rowInfo.changeType == ChangeType.Updated)
                {
                    string newVal;
                    bool   isChanged = isEntityValueChanged(rowInfo, fieldInfo.fieldName, out newVal);
                    if (isChanged)
                    {
                        this.ValidationHelper.CheckValue(fieldInfo, newVal);
                    }
                    if (isChanged)
                    {
                        mustBeChecked.AddLast(fieldInfo.fieldName);
                    }
                }
            }

            rowInfo.changeState.NamesOfChangedFields = mustBeChecked.ToArray();
            MethodInfo methInfo = this.GetOperMethodInfo(dbSetInfo, OperationNames.VALIDATE);

            if (methInfo != null)
            {
                errs = (IEnumerable <ValidationErrorInfo>)methInfo.Invoke(this, new object[] { rowInfo.changeState.Entity, rowInfo.changeState.NamesOfChangedFields });
            }

            if (errs != null && errs.Count() > 0)
            {
                rowInfo.changeState.ValidationErrors = errs.ToArray();
                return(false);
            }

            return(true);
        }
示例#14
0
        protected void UpdateEntityFromRowInfo(object entity, RowInfo rowInfo, bool isOriginal)
        {
            DbSetInfo dbSetInfo = rowInfo.dbSetInfo;
            var       values    = rowInfo.values;
            var       flds      = dbSetInfo.GetFieldByNames();

            foreach (ValueChange fv in values)
            {
                FieldInfo finfo = flds[fv.fieldName];

                if (!finfo.isIncludeInResult())
                {
                    continue;
                }
                if (isOriginal)
                {
                    if ((fv.flags & ValueFlags.Setted) == ValueFlags.Setted)
                    {
                        this.DataHelper.SetValue(entity, finfo, fv.orig);
                    }
                }
                else
                {
                    switch (rowInfo.changeType)
                    {
                    case ChangeType.Deleted:
                    {
                        //For delete fill only original values
                        if ((fv.flags & ValueFlags.Setted) == ValueFlags.Setted)
                        {
                            this.DataHelper.SetValue(entity, finfo, fv.orig);
                        }
                    }
                    break;

                    case ChangeType.Added:
                    {
                        if (finfo.isAutoGenerated)
                        {
                            continue;
                        }
                        if ((fv.flags & ValueFlags.Changed) == ValueFlags.Changed)
                        {
                            if (finfo.isReadOnly && fv.val != null && !finfo.allowClientDefault)
                            {
                                throw new DomainServiceException(string.Format(ErrorStrings.ERR_PROPERTY_IS_READONLY, finfo.fieldName));
                            }
                            if (finfo.isAutoGenerated && fv.val != null)
                            {
                                throw new DomainServiceException(string.Format(ErrorStrings.ERR_PROPERTY_IS_READONLY, finfo.fieldName));
                            }
                            this.DataHelper.SetValue(entity, finfo, fv.val);
                        }
                    }
                    break;

                    case ChangeType.Updated:
                    {
                        if ((fv.flags & ValueFlags.Changed) == ValueFlags.Changed)
                        {
                            if (finfo.isReadOnly || (finfo.isPrimaryKey > 0 || finfo.isRowTimeStamp || finfo.isAutoGenerated))
                            {
                                throw new DomainServiceException(string.Format(ErrorStrings.ERR_PROPERTY_IS_READONLY, finfo.fieldName));
                            }
                            if (!finfo.isNullable && fv.val == null)
                            {
                                throw new DomainServiceException(string.Format(ErrorStrings.ERR_FIELD_IS_NOT_NULLABLE, finfo.fieldName));
                            }
                            this.DataHelper.SetValue(entity, finfo, fv.val);
                        }
                        else if ((fv.flags & ValueFlags.Setted) == ValueFlags.Setted)
                        {
                            if ((finfo.isPrimaryKey > 0 || finfo.isRowTimeStamp || finfo.isNeedOriginal) && fv.val != fv.orig)
                            {
                                throw new DomainServiceException(string.Format(ErrorStrings.ERR_VAL_ORIGINAL_INVALID, finfo.fieldName));
                            }
                            this.DataHelper.SetValue(entity, finfo, fv.val);
                        }
                    }
                    break;
                    }
                }
            }

            if (!isOriginal && rowInfo.changeType == ChangeType.Added)
            {
                foreach (var pn in rowInfo.changeState.ParentRows)
                {
                    if (!this.DataHelper.SetProperty(entity, pn.association.childToParentName, pn.ParentRow.changeState.Entity))
                    {
                        throw new DomainServiceException(string.Format(ErrorStrings.ERR_CAN_NOT_SET_PARENT_FIELD, pn.association.childToParentName, rowInfo.dbSetInfo.EntityType.Name));
                    }
                }
            }
        }
示例#15
0
 protected MethodInfo GetOperMethodInfo(DbSetInfo dbSetInfo, string oper)
 {
     return(dbSetInfo.getOperationMethodInfo(oper));
 }
示例#16
0
        private void CreateIncludedResult(DbSetInfo dbSetInfo, IEnumerable <object> inputEntities, string propertyName, string[] nextParts, Dictionary <string, IncludedResult> visited)
        {
            var       metadata        = this.EnsureMetadataInitialized();
            bool      isChildProperty = false;
            DbSetInfo nextDbSetInfo   = null;
            var       assoc           = metadata.associations.Values.Where(a => a.parentDbSetName == dbSetInfo.dbSetName && a.parentToChildrenName == propertyName).FirstOrDefault();

            if (assoc != null)
            {
                isChildProperty = true;
                nextDbSetInfo   = metadata.dbSets[assoc.childDbSetName];
            }
            else
            {
                assoc = metadata.associations.Values.Where(a => a.childDbSetName == dbSetInfo.dbSetName && a.childToParentName == propertyName).FirstOrDefault();
                if (assoc == null)
                {
                    throw new DomainServiceException(string.Format(ErrorStrings.ERR_INCL_NAVIG_INVALID, propertyName + (nextParts.Length > 0?("." + string.Join(".", nextParts)):"")));
                }

                nextDbSetInfo = metadata.dbSets[assoc.parentDbSetName];
            }
            if (visited.ContainsKey(nextDbSetInfo.dbSetName + "." + propertyName))
            {
                return;
            }

            int    rowCount = 0;
            object propValue;
            LinkedList <object> resultEntities = new LinkedList <object>();

            foreach (object entity in inputEntities)
            {
                propValue = this.DataHelper.GetProperty(entity, propertyName);
                if (isChildProperty && propValue is IEnumerable)
                {
                    foreach (object childEntity in (IEnumerable)propValue)
                    {
                        resultEntities.AddLast(childEntity);
                        ++rowCount;
                    }
                }
                else if (!isChildProperty && propValue != null)
                {
                    resultEntities.AddLast(propValue);
                    ++rowCount;
                }
            }

            //create temporary result without rows
            //fills rows at the end of the method
            IncludedResult current = new IncludedResult {
                dbSetName = nextDbSetInfo.dbSetName, rows = new Row[0], names = nextDbSetInfo.fieldInfos.Where(f => f.isIncludeInResult()).OrderBy(f => f._ordinal).Select(fi => fi.fieldName)
            };

            visited.Add(nextDbSetInfo.dbSetName + "." + propertyName, current);

            if (nextParts.Length > 0)
            {
                this.CreateIncludedResult(nextDbSetInfo, resultEntities, nextParts[0], nextParts.Skip(1).ToArray(), visited);
            }

            //map rows by PK
            Dictionary <string, Row> rows = new Dictionary <string, Row>(rowCount);
            var fields   = nextDbSetInfo.fieldInfos.Where(f => f.isIncludeInResult()).OrderBy(f => f._ordinal).ToArray();
            int fieldCnt = fields.Length;

            FieldInfo[] pkInfos = nextDbSetInfo.GetPKFieldInfos();
            int         counter = 0;

            foreach (object entity in resultEntities)
            {
                Row      row = new Row();
                string[] pk  = new string[pkInfos.Length];
                row.values = new string[fieldCnt];
                for (int i = 0; i < fieldCnt; ++i)
                {
                    string    fv  = null;
                    FieldInfo fld = fields[i];

                    fv = this.DataHelper.GetFieldValueAsString(entity, fld.fieldName);

                    int keyIndex = Array.IndexOf(pkInfos, fld);
                    if (keyIndex > -1)
                    {
                        pk[keyIndex] = fv;
                    }
                    row.values[i] = fv;
                }
                row.key = string.Join(";", pk);
                //here we filter out repeated rows
                if (!rows.ContainsKey(row.key))
                {
                    rows.Add(row.key, row);
                    ++counter;
                }
            }

            current.rows     = rows.Values;
            current.rowCount = counter;
        }