private List <dynamic> DetermineRequiredJoinRecords <ONE, MANY>(EntityMetaData joinTableMD, object[] fkValues1, List <object[]> fkValuesM) where ONE : class where MANY : class { try { var entityOneMD = entityMetaData.GetMeta4Entity <ONE>(); var entityManyMD = entityMetaData.GetMeta4Entity <MANY>(); List <EdmProperty> joinTableKeyOnePart = property.GetProjectedFKProperties(joinTableMD, entityOneMD); List <EdmProperty> joinTableKeyManyPart = property.GetProjectedFKProperties(joinTableMD, entityManyMD); Type joinType = Type.GetType(joinTableMD.entity.FullName); var joinRecords = new List <dynamic>(); for (int row = 0; row < fkValuesM.Count(); row++) { joinRecords.Add(Activator.CreateInstance(joinType)); } property.SetPropertyValues(joinType, joinRecords, joinTableKeyOnePart, fkValues1); property.SetPropertyValues(joinType, joinRecords, joinTableKeyManyPart, fkValuesM); return(joinRecords); } catch (Exception e) { throw e; } }
public JoinTable(DbContext context, GenericDataRepository repos, EntityMetaData entityMetaData) { this.entityMetaData = entityMetaData; this.context = context; this.repos = repos; property = new Property(entityMetaData); }
public GenericDataRepository(DbContext context) { entityMetaData = new EntityMetaData(context); this.context = context; joinTable = new JoinTable(context, this, entityMetaData); property = new Property(entityMetaData); }
private async Task <Boolean> CheckOutboundReferences(dynamic record, Action action) { EntityMetaData recordMD = entityMetaData.GetMeta4Entity(record); if (recordMD == null) { throw new ArgumentException("Entity type unknown in repository."); } foreach (var foreignKey in recordMD.outRefs) { if (!CheckMetaDataArguments(foreignKey)) { return(false); } object[] KeyValues = property.GetPropertyValues(record, foreignKey.foreignKeyProperties); if (NullAllowedAndPresent(foreignKey, KeyValues)) { break; } int recordCnt = (await CountOccurencesOfEntityAsync( foreignKey.referredEntity.entity, foreignKey.foreignKeyProjectionProperties, KeyValues)); switch (action) { case Action.CREATE: case Action.UPDATE: { if (!NumberOfRecordsMatchesMultiplicity(recordCnt, foreignKey.multiplicity)) { return(false); } break; } case Action.DELETE: { if (recordCnt > 0 && foreignKey.deleteBehavior == OperationAction.Cascade) { return(await CascadeByDeleteAsync( // recursion foreignKey.referredEntity.entity, foreignKey.foreignKeyProjectionProperties, KeyValues)); } break; } default: { throw new ArgumentException("Switch error."); } } } return(true); }
internal List <EdmProperty> GetFKProperties(EntityMetaData principalEntityMD, EntityMetaData dependentEntityMD) { foreach (var outRef in dependentEntityMD.outRefs) { if (outRef.referredEntity == principalEntityMD) { return(outRef.foreignKeyProperties); } } return(null); }
// For Insert: For the potential new situation: Outbound references: If fkKey is nullable AND contains nullvalues then allow else see function "NumberOfRecordsMatchesMultiplicity" // Inbound references: no test needed. // For Delete: For the potential new situation: Outbound references: First check for Cascade deletes, if so Cascade the deletion else always allow // Inbound references: See functon "NumberOfRecordsMatchesMultiplicity4Delete" // For Update: For the potential new situation: Outbound references: Same as Insert. // Inbound references: Always allow private async Task <Boolean> CheckInboundReferences(dynamic record) { EntityMetaData recordMD = entityMetaData.GetMeta4Entity(record); if (recordMD == null) { throw new ArgumentException("Entity type unknown in repository."); } foreach (var inRefEntity in recordMD.inRefs) { foreach (var foreignKey in inRefEntity.outRefs) // foreignKey inRef---->----references---->record (= record to delete) { if (foreignKey.referredEntity != recordMD) { break; //only Inrefs to "me" } { // now we have got all the inbound references. if (!CheckMetaDataArguments(foreignKey)) { return(false); } object[] KeyValues = property.GetPropertyValues(record, foreignKey.foreignKeyProjectionProperties); if (NullAllowedAndPresent(foreignKey, KeyValues)) { break; } int Referrers = await CountOccurencesOfEntityAsync( inRefEntity.entity, foreignKey.foreignKeyProperties, KeyValues); if (Referrers == 0) { break; // Nobody is referring to current record, so no need to check! } int recordCnt = await CountOccurencesOfEntityAsync( foreignKey.referredEntity.entity, foreignKey.foreignKeyProjectionProperties, KeyValues); if (!NumberOfRecordsMatchesMultiplicity4Delete(recordCnt, foreignKey.multiplicity)) { return(false); } break; } } } return(true); }
private async Task <List <dynamic> > GetJoinRecordsAsync <ONE, MANY>(EntityMetaData joinTableMD, object[] fkValues1) where ONE : class where MANY : class { try { var entityOneMD = entityMetaData.GetMeta4Entity <ONE>(); List <EdmProperty> PartialKey = property.GetProjectedFKProperties(joinTableMD, entityOneMD); return(await repos.GetByConstructedKeyAsync(joinTableMD.entity, PartialKey, fkValues1, "", false)); } catch (Exception e) { throw e; } }
private EntityMetaData.OutboundReferences FindRef(EntityMetaData referringEntity, EntityMetaData referredEntity) { if (referringEntity.outRefs == null) { return(null); } foreach (var outref in referringEntity.outRefs) { if (outref.referredEntity == referredEntity) { return(outref); } } return(null); }
public EntityMetaData GetMeta4JoinEntity(EntityMetaData leftRecord, EntityMetaData rightRecord) { if (leftRecord == null || rightRecord == null) { throw new ArgumentException("Entity type unknown in repository."); } foreach (var leftPrincipal in leftRecord.outRefs) { foreach (var rightPrincipal in rightRecord.outRefs) { if (leftPrincipal.referredEntity == rightPrincipal.referredEntity) { return(leftPrincipal.referredEntity); } } } return(null); }
private EntityMetaData DetermineJoinTable <ONE, MANY>() where ONE : class where MANY : class { try { EntityMetaData joinTableMD = entityMetaData.GetMeta4JoinEntity( entityMetaData.GetMeta4Entity <ONE>(), entityMetaData.GetMeta4Entity <MANY>()); if (joinTableMD == null) { throw new ArgumentException("Entity type unknown in repository."); } return(joinTableMD); } catch (Exception e) { throw e; } }
private EntityMetaData.OutboundReferences SetForeignKeyInfo( EntityMetaData currentEntity, EntityMetaData referredEntity, List <EdmProperty> foreignKeyProperties, List <EdmProperty> projectionOfForeignKeyProperties, OperationAction DeleteBehavior, RelationshipMultiplicity RelationshipMultiplicity) { if (foreignKeyProperties == null || foreignKeyProperties.Count() == 0) { return(null); } return(new EntityMetaData.OutboundReferences() { foreignKeyProperties = foreignKeyProperties, foreignKeyProjectionProperties = projectionOfForeignKeyProperties, referredEntity = referredEntity, deleteBehavior = DeleteBehavior, multiplicity = RelationshipMultiplicity, Nullable = foreignKeyProperties.First().Nullable }); }
internal List <PropertyInfo> GetPropertyInfoPropsOfEntity(EntityMetaData joinTableMD) { Type joinType = Type.GetType(joinTableMD.entity.FullName); return(joinType.GetProperties().ToList()); }
public Property(EntityMetaData entityMetaData) { this.entityMetaData = entityMetaData; }
private async Task <List <dynamic> > DetermineActualJoinRecordsAsync <ONE, MANY>(EntityMetaData joinTableMD, object[] fkValues1) where ONE : class where MANY : class { try { Type joinType = Type.GetType(joinTableMD.entity.FullName); List <dynamic> selection = await GetJoinRecordsAsync <ONE, MANY>(joinTableMD, fkValues1); return(selection); } catch (Exception e) { throw e; } }
private async Task <HttpStatusCode> UpdateJoinEntityRecordsAsync <dynamic>(EntityMetaData joinTableMD, List <dynamic> now, List <dynamic> target) where dynamic : class { HttpStatusCode result = HttpStatusCode.OK; if (now == null && target == null) { return(result); } if (target == null) { target = new List <dynamic>(); } if (now == null) { now = new List <dynamic>(); } List <dynamic> alreadyOk = new List <dynamic>(); List <dynamic> recordsToDelete = new List <dynamic>(); List <dynamic> recordsToAdd = new List <dynamic>(); var propIes = property.GetPropertyInfoPropsOfEntity(joinTableMD); Boolean processed = false; foreach (var record1 in now) { processed = false; foreach (var record2 in target) { if (RecordsAreEqual(propIes, record1, record2)) { alreadyOk.Add(record1); target.Remove(record2); processed = true; break; } } if (!processed) { recordsToDelete.Add(record1); } } foreach (var record2 in target) { recordsToAdd.Add(record2); } foreach (var record in recordsToDelete) { result = await repos._DeleteAsync(record); if (result != HttpStatusCode.OK) { return(result); } } foreach (var record in recordsToAdd) { result = await repos._InsertAsync(record); if (result != HttpStatusCode.OK) { return(result); } } return(result); }
private async Task <List <dynamic> > _GetAsync(EntityMetaData EntityMD, object[] keyValues) { return(await GetByConstructedKeyAsync(EntityMD.entity, EntityMD.primaryKeysProperties, keyValues, "", tracking : false)); }