public object ExecuteQuery(Expression expression) { var command = LinqCommandFactory.CreateLinqSelect(this, expression); var result = ExecuteLinqCommand(command); return(result); }
public virtual bool CanDeleteRecord(EntityRecord record, out Type[] blockingEntities) { Util.Check(record != null, "CanDeleteRecord: record parameter may not be null."); blockingEntities = null; var entInfo = record.EntityInfo; var blockingTypeSet = new HashSet <Type>(); //check all external ref members foreach (var refMember in entInfo.IncomingReferences) { // if it is cascading delete, this member is not a problem if (refMember.Flags.IsSet(EntityMemberFlags.CascadeDelete)) { continue; } var fromKey = refMember.ReferenceInfo.FromKey; var checkAnyCmd = LinqCommandFactory.CreateCheckAnyChildRecords(fromKey, record); var exists = ExecuteLinqCommand(checkAnyCmd); if ((bool)exists) { blockingTypeSet.Add(refMember.Entity.EntityType); } } if (blockingTypeSet.Count == 0) { return(true); } blockingEntities = blockingTypeSet.ToArray(); return(false); }
internal int ExecuteLinqNonQuery <TEntity>(IQueryable baseQuery, LinqOperation operation) { Util.CheckParam(baseQuery, nameof(baseQuery)); var updateEnt = Context.App.Model.GetEntityInfo(typeof(TEntity)); var command = LinqCommandFactory.CreateLinqNonQuery(this, baseQuery.Expression, operation, updateEnt); var objResult = this.ExecuteLinqCommand(command); return((int)objResult); }
// Example: records: List<IBook>, listMember: book.Author; so we load authors list for each book private IList <EntityRecord> RunIncludeForListManyToMany(IList <EntityRecord> records, EntityMemberInfo listMember) { var pkInfo = listMember.Entity.PrimaryKey; var keyMembers = pkInfo.ExpandedKeyMembers; Util.Check(keyMembers.Count == 1, "Include expression not supported for entities with composite keys, property: {0}.", listMember); var listInfo = listMember.ChildListInfo; // PK values of records var pkValues = GetMemberValues(records, keyMembers[0].Member); //run include query; it will return LinkTuple list var cmd = LinqCommandFactory.CreateSelectByKeyArrayForListPropertyManyToMany(_session, listInfo, pkValues); var tuples = (IList <LinkTuple>)_session.ExecuteLinqCommand(cmd, withIncludes: false); // Group by parent record, and push groups/lists into individual records var fkMember = listInfo.ParentRefMember.ReferenceInfo.FromKey.ExpandedKeyMembers[0].Member; var tupleGroups = tuples.GroupBy(t => EntityHelper.GetRecord(t.LinkEntity).GetValueDirect(fkMember)).ToList(); foreach (var g in tupleGroups) { var pkValue = new EntityKey(pkInfo, g.Key); // Order_Id -> BookOrder.Id var parent = _session.GetRecord(pkValue); // BookOrder var childList = parent.ValuesTransient[listMember.ValueIndex] as IPropertyBoundList; //BookOrder.Lines, list object if (childList != null && childList.IsLoaded) { continue; } if (childList == null) { childList = parent.InitChildEntityList(listMember); } var groupTuples = g.ToList(); childList.Init(groupTuples); } // Init/clear all lists that were NOT loaded var emptyTuples = new List <LinkTuple>(); foreach (var rec in records) { var childList = rec.ValuesTransient[listMember.ValueIndex] as IPropertyBoundList; //BookOrder.Lines, list object if (childList != null && childList.IsLoaded) { continue; } if (childList == null) { childList = rec.InitChildEntityList(listMember); } childList.Init(emptyTuples); } // collect all target records as function result var targetRecords = tuples.Select(t => EntityHelper.GetRecord(t.TargetEntity)).ToList(); return(targetRecords); }
public IEntityRecordContainer SelectByPrimaryKey(EntityInfo entity, object[] keyValues, LockType lockType = LockType.None, EntityMemberMask mask = null) { var cmd = LinqCommandFactory.CreateSelectByPrimaryKey(this, entity.PrimaryKey, lockType, keyValues); var list = (IList)ExecuteLinqCommand(cmd); if (list.Count == 0) { return(null); } return((IEntityRecordContainer)list[0]); }
// Example: records: List<IBookOrder>, listMember: bookOrder.Lines; so we load lines for each book order private IList <EntityRecord> RunIncludeForListManyToOne(IList <EntityRecord> records, EntityMemberInfo listMember) { var pkInfo = listMember.Entity.PrimaryKey; var expMembers = pkInfo.ExpandedKeyMembers; Util.Check(expMembers.Count == 1, "Include expression not supported for entities with composite keys, property: {0}.", listMember); var pkMember = expMembers[0].Member; // IBookOrder.Id var pkValuesArr = GetMemberValues(records, pkMember); var listInfo = listMember.ChildListInfo; var parentRefMember = listInfo.ParentRefMember; //IBookOrderLine.Order var fromKey = parentRefMember.ReferenceInfo.FromKey; Util.Check(fromKey.ExpandedKeyMembers.Count == 1, "Composite keys are not supported in Include expressions; member: {0}", parentRefMember); var selectCmd = LinqCommandFactory.CreateSelectByKeyArrayForListPropertyManyToOne(_session, listInfo, pkValuesArr); var childEntities = (IList)_session.ExecuteLinqCommand(selectCmd, withIncludes: false); //list of all IBookOrderLine for BookOrder objects in 'records' parameter var childRecs = GetRecordList(childEntities); //setup list properties in parent records var fk = fromKey.ExpandedKeyMembers[0].Member; //IBookOrderLine.Order_Id var groupedRecs = childRecs.GroupBy(rec => rec.GetValueDirect(fk)); //each group is list of order lines for a single book order; group key is BookOrder.Id foreach (var g in groupedRecs) { var pkValue = new EntityKey(pkInfo, g.Key); // Order_Id -> BookOrder.Id var parent = _session.GetRecord(pkValue); // BookOrder var childList = parent.ValuesTransient[listMember.ValueIndex] as IPropertyBoundList; //BookOrder.Lines, list object if (childList != null && childList.IsLoaded) { continue; } if (childList == null) { childList = parent.InitChildEntityList(listMember); } var grpChildEntities = g.Select(r => r.EntityInstance).ToList(); childList.Init(grpChildEntities); } // If for some parent records child lists were empty, we need set the list property to empty list, // If it remains null, it will be considered not loaded, and app will attempt to load it again on first touch foreach (var parent in records) { var value = parent.ValuesTransient[listMember.ValueIndex]; if (value == null) { parent.InitChildEntityList(listMember); } } return(childRecs); }
public void LoadListImpl() { Modified = false; LinkRecordsLookup.Clear(); var status = OwnerRecord.Status; if (status == EntityStatus.Fantom || status == EntityStatus.New) { Entities = new List <IEntityRecordContainer>(); return; } var session = OwnerRecord.Session; var listInfo = OwnerMember.ChildListInfo; var cmd = LinqCommandFactory.CreateSelectByKeyForListPropertyManyToMany(session, listInfo, OwnerRecord.PrimaryKey.Values); var queryRes = session.ExecuteLinqCommand(cmd); var tupleList = (IList <LinkTuple>)queryRes; SetData(tupleList); }
public void LoadListImpl() { Modified = false; var status = OwnerRecord.Status; if (status == EntityStatus.Fantom || status == EntityStatus.New) { Entities = new List <IEntityRecordContainer>(); return; } var fromKey = OwnerMember.ChildListInfo.ParentRefMember.ReferenceInfo.FromKey; var orderBy = OwnerMember.ChildListInfo.OrderBy; var selectCmd = LinqCommandFactory.CreateSelectByKeyForListPropertyManyToOne(OwnerRecord.Session, OwnerMember.ChildListInfo, OwnerRecord.PrimaryKey.Values); var objEntList = (IList)OwnerRecord.Session.ExecuteLinqCommand(selectCmd); var recContList = new List <IEntityRecordContainer>(); foreach (var ent in objEntList) { recContList.Add((IEntityRecordContainer)ent); } Entities = recContList; }
public void ScheduleLinqNonQuery <TEntity>(IQueryable baseQuery, LinqOperation op, CommandSchedule schedule = CommandSchedule.TransactionEnd) { Util.Check(baseQuery is EntityQuery, "query parameter should an EntityQuery."); var model = Context.App.Model; var targetEnt = model.GetEntityInfo(typeof(TEntity)); Util.Check(targetEnt != null, "Generic parameter {0} is not an entity registered in the Model.", typeof(TEntity)); var command = LinqCommandFactory.CreateLinqNonQuery(this, baseQuery.Expression, op, targetEnt); switch (schedule) { case CommandSchedule.TransactionStart: ScheduledCommandsAtStart = ScheduledCommandsAtStart ?? new List <LinqCommand>(); ScheduledCommandsAtStart.Add(command); break; case CommandSchedule.TransactionEnd: ScheduledCommandsAtEnd = ScheduledCommandsAtEnd ?? new List <LinqCommand>(); ScheduledCommandsAtEnd.Add(command); break; } }
private IList <EntityRecord> RunIncludeForEntityRef(IList <EntityRecord> records, EntityMemberInfo refMember) { if (records.Count == 0) { return(_emptyList); } var targetEntity = refMember.ReferenceInfo.ToKey.Entity; var fkMember = refMember.ReferenceInfo.FromKey.ExpandedKeyMembers[0].Member; // r.Book_Id var fkValues = GetMemberValues(records, fkMember); var selectCmd = LinqCommandFactory.CreateSelectByKeyValueArray(_session, targetEntity.PrimaryKey, null, fkValues); var entList = (IList)_session.ExecuteLinqCommand(selectCmd, withIncludes: false); if (entList.Count == 0) { return(_emptyList); } var recList = GetRecordList(entList); // Set ref members in parent records var targetPk = refMember.ReferenceInfo.ToKey; foreach (var parentRec in records) { var fkValue = parentRec.GetValueDirect(fkMember); if (fkValue == DBNull.Value) { parentRec.SetValueDirect(refMember, DBNull.Value); } else { var pkKey = new EntityKey(targetPk, fkValue); //we lookup in session, instead of searching in results of Include query - all just loaded records are registered in session and lookup is done by key (it is fact dict lookup) var targetRec = _session.GetRecord(pkKey); parentRec.SetValueDirect(refMember, targetRec); } } return(recList); }