Example #1
0
        public EntityRecord ReadRecord(IDataRecord dataRecord, EntitySession session)
        {
            // Some outer join queries may produce entities that are null; so we first try to read Primary key values - if they're all null, we return null.
              if (_primaryKeyColumns.Count > 0 && PrimaryKeyIsNull(dataRecord))
            return null;
              var entRec = new EntityRecord(_tableInfo.Entity, EntityStatus.Loading);
              object dbValue = null;
              OutColumnMapping colMap = null;
              //for-i loop is more efficient than foreach
              for (int i = 0; i < _columns.Count; i++) {
            try {
              colMap = _columns[i];
              dbValue = dataRecord[colMap.ReaderColumnIndex];
              //System.Diagnostics.Debug.WriteLine(colMap.DbColumn.ColumnName + " " + dbValue + "(" + dbValue.GetType() + ")");
              var conv = colMap.DbColumn.TypeInfo.ColumnToPropertyConverter;
              if(dbValue != null && conv != null)
            dbValue = conv(dbValue);
              entRec.ValuesOriginal[colMap.DbColumn.Member.ValueIndex] = dbValue;
            } catch (Exception ex) {
              ex.AddValue("DataRecord", dataRecord);
              ex.AddValue("ColumnName", colMap.DbColumn.ColumnName);
              ex.AddValue("DbValue", dbValue);
              throw;
            }

              }
              var sessionRec = session.Attach(entRec); //might return different, previously loaded record
              return sessionRec;
        }
Example #2
0
 public CachedRecordData(EntityRecord record)
 {
     PrimaryKey = record.PrimaryKey;
     Values = new object[record.ValuesOriginal.Length];
     Version = record.Session.Context.EntityCacheVersion;
     Array.Copy(record.ValuesOriginal, Values, Values.Length);
 }
 //If record with the same PK value is already in dictionary, does not add but returns existing one.
 public EntityRecord Add(EntityRecord record)
 {
     var oldRec = Find(record.PrimaryKey);
       if (oldRec != null)
     return oldRec;
       var weakRef = new WeakReference(record);
       _table[record.PrimaryKey] = weakRef;
       return record;
 }
Example #4
0
 public EntityRecord Lookup(EntityKey primaryKey, EntitySession session)
 {
     var strKey = primaryKey.AsString();
       var data = _cacheTable.Lookup(strKey);
       if(data == null)
     return null;
       var needVersion = session.Context.EntityCacheVersion;
       if(data.Version < needVersion) {
     _cacheTable.Remove(primaryKey.AsString());
     return null;
       }
       var rec = new EntityRecord(primaryKey);
       Array.Copy(data.Values, rec.ValuesOriginal, data.Values.Length);
       rec.SourceCacheType = CacheType.Sparse;
       session.Attach(rec);
       return rec;
 }
 //Copies PK values into corresponding FK
 public static void CopyPrimaryKeyToForeign(EntityRecord record, EntityMemberInfo entityRefMember, EntityRecord refTarget)
 {
     var refInfo = entityRefMember.ReferenceInfo;
       var fkMembers = refInfo.FromKey.ExpandedKeyMembers;
       //If target is null, set all to DbNull
       if (refTarget == null) {
     for (int i = 0; i < fkMembers.Count; i++)
       record.SetValueDirect(fkMembers[i].Member, DBNull.Value);
     return;
       }
       //refTarget is not null
       var pkMembers = refInfo.ToKey.ExpandedKeyMembers;
       for (int i = 0; i < pkMembers.Count; i++) {
     //copy value from PK to FK member
     var value = refTarget.GetValueDirect(pkMembers[i].Member);
     record.SetValueDirect(fkMembers[i].Member, value);
       }
 }
Example #6
0
 // Will be overridden SecureSession
 public virtual object RecordGetMemberValue(EntityRecord record, EntityMemberInfo member)
 {
     return(member.GetValueRef(record, member));
 }
 public static object GetSimpleValue(EntityRecord record, EntityMemberInfo member)
 {
     var value = record.GetValueDirect(member);
       if (value == null && record.Status != EntityStatus.New) {
     record.Reload();
     value = record.GetValueDirect(member);
       }
       if (value == DBNull.Value)
     return null;
       return value;
 }
Example #8
0
 public static int CompareTopologicalIndexes(EntityRecord x, EntityRecord y)
 {
     var entIndexCompare = x.SortIndex.CompareTo(y.SortIndex);
       if (entIndexCompare != 0)
     return entIndexCompare;
       return x.SortSubIndex.CompareTo(y.SortSubIndex);
 }
Example #9
0
 public EntityBase(EntityRecord record)
 {
     Record = record;
 }
 // The property on interface is not nullable (int), but the column in database is. We substitute the default value for type (0)
 // with DbNull.Value
 public static object GetValueTypeReplaceNullWithDefault(EntityRecord record, EntityMemberInfo member)
 {
     var value = GetSimpleValue(record, member);
       if (value == DBNull.Value)
     return member.DefaultValue;
       return value;
 }
 object GetValue(EntityRecord record, EntityMemberInfo member)
 {
     var v = record.GetValueDirect(member);
       if(v != null) {
     if(v == DBNull.Value)
       return null;
     var rec = (EntityRecord)v;
     return rec.EntityInstance;
       }
       //retrieve entity
       var targetPk = EntityKey.CreateSafe(_targetEntity.PrimaryKey, record.PrimaryKey.Values);
       var targetRec = record.Session.GetRecord(targetPk);
       if (targetRec == null) {
     record.SetValueDirect(member, DBNull.Value);
     return null;
       }
       record.SetValueDirect(member, targetRec);
       if(targetRec.ByRefUserPermissions == null)
     targetRec.ByRefUserPermissions = member.ByRefPermissions;
       return targetRec.EntityInstance;
 }
Example #12
0
        public bool TryExecuteSelect(EntitySession session, EntityCommand command, object[] args, out IList<EntityRecord> records)
        {
            records = _empty;
              if(!Settings.CacheEnabled || session.CacheDisabled)
            return false;
              if (!string.IsNullOrWhiteSpace(command.Filter))
            return false;
              var cachingType = command.TargetEntityInfo.CacheType;
              if(cachingType == CacheType.None)
            return false;
              switch(cachingType) {
            case CacheType.None: return false;
            case CacheType.FullSet:
              var start = _timeService.ElapsedMilliseconds;
              var result = _fullSetCache.TryExecuteSelect(session, command, args, out records);
              if(result) {
            var end = _timeService.ElapsedMilliseconds;
            var rowCount = records == null ? 0 : records.Count;
            LogCommand(session, command, args, cachingType, end - start, rowCount);
              }
              return result;

            case CacheType.Sparse:
              var getByPk = command.Kind == EntityCommandKind.SelectByKey && command.SelectKey.KeyType.IsSet(KeyType.PrimaryKey);
              if(getByPk) {
            var pk = new EntityKey(command.SelectKey, args);
            var rec = _sparseCache.Lookup(pk, session);
            if(rec != null) {
              records = new EntityRecord[] { rec };
              LogCommand(session, command, args, cachingType, 0, 1);
              return true;
            }
              }
              return false;
              }//switch
              return false;
        }
Example #13
0
 void SaveEvents_SavingChanges(EntityRecord record, EventArgs args)
 {
     if(ActionType == TrackingActionType.Created && record.Status == EntityStatus.New ||
       ActionType == TrackingActionType.Updated && (record.Status == EntityStatus.New || record.Status == EntityStatus.Modified)) {
     //Do it directly, to bypass authorization checks (it should still work with record.SetValue)
     record.ValuesModified[_member.ValueIndex] = record.Session.NextTransactionId;
       }
 }
 public static void SetValueTypeReplaceDefaultWithNull(EntityRecord record, EntityMemberInfo member, object value)
 {
     if (value == member.DefaultValue)
     value = DBNull.Value;
       SetSimpleValue(record, member, value);
 }
 //Utilities
 private static void MarkTargetToClearLists(EntityRecord record, EntityMemberInfo member, object newEntityRef)
 {
     //If record is not new, mark old ref to clear lists
       if (record.Status != EntityStatus.New) {
     EntityRecord oldTargetRec;
     var oldTarget = record.ValuesTransient[member.ValueIndex];
     if(oldTarget == null)
       oldTargetRec = GetEntityRefTarget(record, member);
     else
       oldTargetRec = EntityHelper.GetRecord(oldTarget);
     if(oldTargetRec != null)
       oldTargetRec.MarkForClearLists();
       }
       //Check new ref
       if(newEntityRef != null) {
     var newTargetRec = EntityHelper.GetRecord(newEntityRef);
     if(newTargetRec != null)
       newTargetRec.MarkForClearLists();
       }
 }
 public static void SetTransientValue(EntityRecord record, EntityMemberInfo member, object value)
 {
     record.ValuesTransient[member.ValueIndex] = value;
 }
 public static void SetSimpleValue(EntityRecord record, EntityMemberInfo member, object value)
 {
     if (value == null)
     value = DBNull.Value;
       var oldValue = record.GetValueDirect(member);
       if (member.AreValuesEqual(oldValue, value))
     return;
       record.SetValueDirect(member, value);
       if (record.Status == EntityStatus.Loaded)
     record.Status = EntityStatus.Modified;
 }
 public static void SetEntityRefValue(EntityRecord record, EntityMemberInfo member, object value)
 {
     //If there's list on the other side, mark target records( old ref and new ref) to clear lists.
       if(member.ReferenceInfo.TargetListMember != null)
     MarkTargetToClearLists(record, member, value);
       EntityRecord newRec = null;
       if (value == null)
     value = DBNull.Value;
       if (value == DBNull.Value) {
     record.ValuesTransient[member.ValueIndex] = DBNull.Value;
       } else {
     newRec = EntityHelper.GetRecord(value);
     Util.Check(newRec != null, "Invalid entity ref value - not an entity: {0}", value);
     record.ValuesTransient[member.ValueIndex] = newRec;
     if(newRec.ByRefUserPermissions == null)
       newRec.ByRefUserPermissions = member.ByRefPermissions;
       }
       CopyPrimaryKeyToForeign(record, member, newRec);
       if (record.Status == EntityStatus.Loaded)
     record.Status = EntityStatus.Modified;
 }
Example #19
0
 public void Remove(EntityRecord record)
 {
     var key = record.PrimaryKey.AsString();
       _cacheTable.Remove(key);
 }
Example #20
0
 protected void ReadCrudOutputParameterValues(IDbCommand command, DbCommandInfo commandInfo, EntityRecord record)
 {
     for (int i = 0; i < commandInfo.OutputParameters.Count; i++) {
     var prmInfo = commandInfo.OutputParameters[i];
     var col = prmInfo.SourceColumn;
     if (col == null) continue;
     var prm = command.Parameters[prmInfo.Name] as IDbDataParameter;
     var value = prm.Value;
     var conv = prmInfo.TypeInfo.ColumnToPropertyConverter;
     if (value != DBNull.Value && conv != null)
       value = conv(value);
     record.ValuesModified[col.Member.ValueIndex] = value;
       }//for
 }
Example #21
0
 public virtual void RecordSetMemberValue(EntityRecord record, EntityMemberInfo member, object value)
 {
     member.SetValueRef(record, member, value);
 }
Example #22
0
 private void SetCrudCommandParameterValues(DbCommandInfo commandInfo, IDbCommand command, EntityRecord record)
 {
     if (record.Status == EntityStatus.Stub)
     record.Reload();
       for (int i = 0; i < commandInfo.Parameters.Count; i++) {
     var prm = (IDbDataParameter)command.Parameters[i];
     prm.Value = DBNull.Value;
     var prmInfo = commandInfo.Parameters[i];
     var isInput = prmInfo.Direction == ParameterDirection.Input || prmInfo.Direction == ParameterDirection.InputOutput;
     if (!isInput)  continue;
     var col = prmInfo.SourceColumn;
     if (col == null || col.Member == null) continue;
     var value = record.GetValueDirect(col.Member);
     if(value == null)
       value = DBNull.Value;
     var conv = prmInfo.TypeInfo.PropertyToColumnConverter;
     if (value != DBNull.Value && conv != null)
       value = conv(value);
     prm.Value = value;
       } //for i
 }
Example #23
0
 public EntityKey(EntityKeyInfo keyInfo, EntityRecord record)
 {
     KeyInfo = keyInfo;
     Values  = new object[KeyInfo.ExpandedKeyMembers.Count];
     CopyValues(record);
 }
 public static object GetTransientValue(EntityRecord record, EntityMemberInfo member)
 {
     return record.ValuesTransient[member.ValueIndex];
 }
Example #25
0
 internal DbCommandInfo GetDbCommandForSave(EntityRecord record)
 {
     var crud = record.EntityInfo.CrudCommands;
       EntityCommand entCmd;
       switch (record.Status) {
     case EntityStatus.New: entCmd = crud.Insert; break;
     case EntityStatus.Modified: entCmd = crud.Update; break;
     case EntityStatus.Deleting: entCmd = crud.Delete; break;
     default:
       return null;
       }
       var cmdInfo = GetDbCommandInfo(entCmd);
       return cmdInfo;
 }
 public static object DummyGetValue(EntityRecord record, EntityMemberInfo member)
 {
     return null;
 }
Example #27
0
 private void ApplyUpdate(DataConnection connection, EntityRecord record)
 {
     var cmdInfo = GetDbCommandForSave(record);
       Util.Check(cmdInfo != null, "Failed to find update/insert/delete command for entity {0}, status {1).",
                record.EntityInfo.Name, record.Status);
       try {
     var cmd = CreateDbCommand(cmdInfo, connection);
     SetCrudCommandParameterValues(cmdInfo, cmd, record);
     ExecuteDbCommand(cmd, connection, DbExecutionType.NonQuery);
     if(cmdInfo.PostUpdateActions.Count > 0)
       foreach(var action in cmdInfo.PostUpdateActions)
     action(connection, cmd, record);
     record.SubmitCount++;
     record.EntityInfo.SaveEvents.OnSubmittedChanges(record);
       } catch(Exception ex) {
     ex.AddValue("entity-command-name", cmdInfo.EntityCommand.CommandName);
     ex.AddValue("record", record);
     throw;
       }
 }
 public static void DummySetValue(EntityRecord record, EntityMemberInfo member, object value)
 {
 }
Example #29
0
 private bool ShouldUpdate(EntityRecord record)
 {
     if (record.Status == EntityStatus.Modified && record.EntityInfo.Flags.IsSet(EntityFlags.NoUpdate))
     return false; //if for whatever reason we have such a record, just ignore it
       if(record.Status == EntityStatus.Fantom)
     return false;
       return true;
 }
 // When we get the value, if it is null, we must try to load the list
 public static object GetEntityListValue(EntityRecord record, EntityMemberInfo member)
 {
     var list = record.ValuesTransient[member.ValueIndex];
       if (list != null)
     return list;
       //create new list
       list = record.InitChildEntityList(member);
       return list;
 }
 void SetValue(EntityRecord record, EntityMemberInfo member, object value)
 {
     Util.Throw("Back-ref properties are readonly, cannot set value. Property: {0}.{1}",
     member.Entity.Name, member.MemberName);
 }
        private void AddRecordUpdateToBatch(EntityRecord rec)
        {
            CheckCurrentCommand();
              var dbCmd = _currentCommand.DbCommand;
              var argValues = new List<string>();
              var cmdInfo = _db.GetDbCommandForSave(rec);
              foreach (var prmInfo in cmdInfo.Parameters) {
            var col = prmInfo.SourceColumn;
            //Check if we need to use already defined parameter;
            // this happens when we insert parent and child records with parent having identity primary key column
            if (_updateSet.UsesOutParams && col != null && col.Flags.IsSet(DbColumnFlags.IdentityForeignKey)) {
              //Find out parameter that returns the identity of the parent record
              var parentRec = rec.GetValueDirect(col.Member.ForeignKeyOwner) as EntityRecord;
              if (parentRec != null && parentRec.CustomTag != null) {
            //parentRec has identity PK, and is already in _identities list
            var idSource = (IdentitySource) parentRec.CustomTag;
            if (idSource.BatchCommand == _currentCommand)
              argValues.Add(idSource.Parameter.ParameterName); //if it is the same command, just add ref to parameter
            else {
              //different command - create new parameter, and add action to copy param value from source
              // dbCmd.Parameters.Add(idSource.Parameter); //this does not work - parameters cannot be shared between commands
              var dbParam = _driver.AddParameter(dbCmd, prmInfo);
              //override parameter name
              dbParam.ParameterName = _driver.DynamicSqlParameterPrefix + "P" + (dbCmd.Parameters.Count - 1);
              argValues.Add(dbParam.ParameterName);
              var sourcePrm = idSource.Parameter;
              idSource.BatchCommand.AddPostAction(() => dbParam.Value = sourcePrm.Value);
            }
            continue; //next param
              }
            }//if

            //Get the value, analyze it, see if it is ok to use literal or it's better to put the value into parameter
            var value = rec.GetValueDirect(col.Member);
            if (value == null)
              value = DBNull.Value;
            var conv = prmInfo.TypeInfo.PropertyToColumnConverter;
            if (value != DBNull.Value && conv != null)
              value = conv(value);
            if (BatchShouldUseParameterFor(prmInfo, value)) {
              //create parameter
              var dbParam = _driver.AddParameter(dbCmd, prmInfo);
              //override parameter name
              dbParam.ParameterName = _driver.DynamicSqlParameterPrefix + "P" + (dbCmd.Parameters.Count - 1);
              dbParam.Value = value;
              //If it is parameter holding identity returned from stored proc, then save its info in the rec.CustomTag
              bool isIdentityOut = rec.Status == EntityStatus.New && col.Flags.IsSet(DbColumnFlags.Identity)
            && dbParam.Direction == ParameterDirection.Output;
              if (isIdentityOut)
            rec.CustomTag = new IdentitySource() { BatchCommand = _currentCommand, Parameter = dbParam};

              //add reference to parameter in arg list
              var strArg = dbParam.ParameterName;
              if (dbParam.Direction != ParameterDirection.Input) {
            strArg = string.Format(_driver.CommandCallOutParamFormat, strArg);
            //copy value returned from sp into entity property
            _currentCommand.AddPostAction(() =>
                 rec.SetValueDirect(col.Member, dbParam.Value)
                 );
              }
              argValues.Add(strArg);
            } else {
              string argValue;
              if (value == DBNull.Value)
            argValue = "NULL";
              else
            argValue = prmInfo.TypeInfo.ToLiteral(value);
              argValues.Add(argValue);
            }// if BatchShouldUseParameterFor
              }//foreach prm
              //format method call
              var strArgs = string.Join(", ", argValues);
              var strCall = string.Format(_driver.CommandCallFormat, cmdInfo.FullCommandName, strArgs);
              //append it to sql
              _sqlBuilder.AppendLine(strCall);
        }
Example #33
0
 private static bool UsesOutParam(EntityRecord record)
 {
     var flags = record.EntityInfo.Flags;
       return flags.IsSet(EntityFlags.HasRowVersion) || (flags.IsSet(EntityFlags.HasIdentity) && record.Status == EntityStatus.New);
 }
Example #34
0
 public void RegisterForClearLists(EntityRecord record)
 {
     // may need some concurrency safety (for m-threaded session)
     this.RecordsToClearLists.Add(record);
 }
 public PropertyBoundListManyToOne(EntityRecord ownerRecord, EntityMemberInfo ownerMember) : base(ownerRecord, ownerMember)
 {
 }
Example #36
0
 public void Add(EntityRecord record)
 {
     var data = new CachedRecordData(record);
       var key = record.PrimaryKey.AsString();
       _cacheTable.Add(key, data);
 }