internal string ToUserString() { string childColsString = MemberPath.PropertiesToUserString(m_childColumns, false); string parentColsString = MemberPath.PropertiesToUserString(m_parentColumns, false); string result = System.Data.Entity.Strings.ViewGen_Foreign_Key(m_fKeySet.Name, m_childTable.Name, childColsString, m_parentTable.Name, parentColsString); return(result); }
internal string ToUserString() { var childColsString = MemberPath.PropertiesToUserString(m_childColumns, false); var parentColsString = MemberPath.PropertiesToUserString(m_parentColumns, false); var result = Strings.ViewGen_Foreign_Key( m_fKeySet.Name, m_childTable.Name, childColsString, m_parentTable.Name, parentColsString); return(result); }
/// <summary> /// Checks: /// 1) Concurrency token is not defined in this Extent's ElementTypes' derived types /// 2) Members with concurrency token should not have conditions specified /// </summary> private void CheckConcurrencyControlTokens() { Debug.Assert(m_viewTarget == ViewTarget.QueryView); // Get the token fields for this extent var extentType = m_extent.ElementType; var tokenMembers = MetadataHelper.GetConcurrencyMembersForTypeHierarchy(extentType, m_edmItemCollection); var tokenPaths = new Set <MemberPath>(MemberPath.EqualityComparer); foreach (var tokenMember in tokenMembers) { if (!tokenMember.DeclaringType.IsAssignableFrom(extentType)) { var message = Strings.ViewGen_Concurrency_Derived_Class(tokenMember.Name, tokenMember.DeclaringType.Name, m_extent); var record = new ErrorLog.Record(ViewGenErrorCode.ConcurrencyDerivedClass, message, m_cellWrappers, String.Empty); ExceptionHelpers.ThrowMappingException(record, m_config); } tokenPaths.Add(new MemberPath(m_extent, tokenMember)); } if (tokenMembers.Count > 0) { foreach (var wrapper in m_cellWrappers) { var conditionMembers = new Set <MemberPath>( wrapper.OnlyInputCell.CQuery.WhereClause.MemberRestrictions.Select(oneOf => oneOf.RestrictedMemberSlot.MemberPath), MemberPath.EqualityComparer); conditionMembers.Intersect(tokenPaths); if (conditionMembers.Count > 0) { // There is a condition on concurrency tokens. Throw an exception. var builder = new StringBuilder(); builder.AppendLine( Strings.ViewGen_Concurrency_Invalid_Condition( MemberPath.PropertiesToUserString(conditionMembers, false), m_extent.Name)); var record = new ErrorLog.Record( ViewGenErrorCode.ConcurrencyTokenHasCondition, builder.ToString(), new[] { wrapper }, String.Empty); ExceptionHelpers.ThrowMappingException(record, m_config); } } } }
internal override bool VisitLeaf(LeafCellTreeNode node, bool dummy) { // make sure all projected attributes in wrapper correspond exactly to those in node var thisQuery = m_wrapper.RightCellQuery; var thatQuery = node.LeftCellWrapper.RightCellQuery; var collidingColumns = new List <MemberPath>(); if (thisQuery != thatQuery) { for (var i = 0; i < thisQuery.NumProjectedSlots; i++) { var thisSlot = thisQuery.ProjectedSlotAt(i) as MemberProjectedSlot; if (thisSlot != null) { var thatSlot = thatQuery.ProjectedSlotAt(i) as MemberProjectedSlot; if (thatSlot != null) { var tableMember = m_viewgenContext.MemberMaps.ProjectedSlotMap[i]; if (!tableMember.IsPartOfKey) { if (!MemberPath.EqualityComparer.Equals(thisSlot.MemberPath, thatSlot.MemberPath)) { collidingColumns.Add(tableMember); } } } } } } if (collidingColumns.Count > 0) { var columnsString = MemberPath.PropertiesToUserString(collidingColumns, false); var message = Strings.ViewGen_NonKeyProjectedWithOverlappingPartitions(columnsString); var record = new ErrorLog.Record( ViewGenErrorCode.NonKeyProjectedWithOverlappingPartitions, message, new[] { m_wrapper, node.LeftCellWrapper }, String.Empty); m_errorLog.AddEntry(record); } return(true); }
// requires: all columns in constraint.ParentColumns and // constraint.ChildColumns must have been mapped in some cell in m_cellGroup // effects: Given the foreign key constraint, checks if the // constraint.ChildColumns are mapped to the constraint.ParentColumns // in m_cellGroup in the right oder. If not, adds an error to m_errorLog and returns // false. Else returns true private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog) { // Go through every cell and find the cells that are relevant to // parent and those that are relevant to child // Then for each cell pair (parent, child) make sure that the // projected foreign keys columns in C-space are aligned var parentCells = new List <Cell>(); var childCells = new List <Cell>(); foreach (var cell in cells) { if (cell.SQuery.Extent.Equals(ChildTable)) { childCells.Add(cell); } if (cell.SQuery.Extent.Equals(ParentTable)) { parentCells.Add(cell); } } // Make sure that all child cells and parent cells align on // the columns, i.e., for each DISTINCT pair C and P, get the columns // on the S-side. Then get the corresponding fields on the // C-side. The fields on the C-side should match var foundParentCell = false; var foundChildCell = false; foreach (var childCell in childCells) { var allChildSlotNums = GetSlotNumsForColumns(childCell, ChildColumns); if (allChildSlotNums.Count == 0) { // slots in present in S-side, ignore continue; } List <MemberPath> childPaths = null; List <MemberPath> parentPaths = null; Cell errorParentCell = null; foreach (var childSlotNums in allChildSlotNums) { foundChildCell = true; // Get the fields on the C-side childPaths = new List <MemberPath>(childSlotNums.Count); foreach (var childSlotNum in childSlotNums) { // Initial slots only have JoinTreeSlots var childSlot = (MemberProjectedSlot)childCell.CQuery.ProjectedSlotAt(childSlotNum); Debug.Assert(childSlot != null); childPaths.Add(childSlot.MemberPath); } foreach (var parentCell in parentCells) { var allParentSlotNums = GetSlotNumsForColumns(parentCell, ParentColumns); if (allParentSlotNums.Count == 0) { // * Parent and child cell are the same - we do not // need to check since we want to check the foreign // key constraint mapping across cells // * Some slots not in present in S-side, ignore continue; } foreach (var parentSlotNums in allParentSlotNums) { foundParentCell = true; parentPaths = new List <MemberPath>(parentSlotNums.Count); foreach (var parentSlotNum in parentSlotNums) { var parentSlot = (MemberProjectedSlot)parentCell.CQuery.ProjectedSlotAt(parentSlotNum); Debug.Assert(parentSlot != null); parentPaths.Add(parentSlot.MemberPath); } // Make sure that the last member of each of these is the same // or the paths are essentially equivalent via referential constraints // We need to check that the last member is essentially the same because it could // be a regular scenario where aid is mapped to PersonAddress and Address - there // is no ref constraint. So when projected into C-Space, we will get Address.aid // and PersonAddress.Address.aid if (childPaths.Count == parentPaths.Count) { var notAllPathsMatched = false; for (var i = 0; i < childPaths.Count && !notAllPathsMatched; i++) { var parentPath = parentPaths[i]; var childPath = childPaths[i]; if (!parentPath.LeafEdmMember.Equals(childPath.LeafEdmMember)) //Child path did not match { if (parentPath.IsEquivalentViaRefConstraint(childPath)) { //Specifying the referential constraint once in the C space should be enough. //This is the only way possible today. //We might be able to derive more knowledge by using boolean logic return(true); } else { notAllPathsMatched = true; } } } if (!notAllPathsMatched) { return(true); //all childPaths matched parentPaths } else { //If not this one, some other Parent Cell may match. errorParentCell = parentCell; } } } } //foreach parentCell } //If execution is at this point, no parent cell's end has matched (otherwise it would have returned true) Debug.Assert(childPaths != null, "child paths should be set"); Debug.Assert(parentPaths != null, "parent paths should be set"); Debug.Assert(errorParentCell != null, "errorParentCell should be set"); var message = Strings.ViewGen_Foreign_Key_ColumnOrder_Incorrect( ToUserString(), MemberPath.PropertiesToUserString(ChildColumns, false), ChildTable.Name, MemberPath.PropertiesToUserString(childPaths, false), childCell.CQuery.Extent.Name, MemberPath.PropertiesToUserString(ParentColumns, false), ParentTable.Name, MemberPath.PropertiesToUserString(parentPaths, false), errorParentCell.CQuery.Extent.Name); var record = new ErrorLog.Record( ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, message, new[] { errorParentCell, childCell }, String.Empty); errorLog.AddEntry(record); return(false); } Debug.Assert(foundParentCell, "Some cell that mapped the parent's key must be present!"); Debug.Assert( foundChildCell == true, "Some cell that mapped the child's foreign key must be present according to the requires clause!"); return(true); }
internal string ToUserString() { return(Strings.ViewGen_Foreign_Key((object)this.m_fKeySet.Name, (object)this.m_childTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>) this.m_childColumns, false), (object)this.m_parentTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>) this.m_parentColumns, false))); }
private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog) { List <Cell> cellList1 = new List <Cell>(); List <Cell> cellList2 = new List <Cell>(); foreach (Cell cell in cells) { if (cell.SQuery.Extent.Equals((object)this.ChildTable)) { cellList2.Add(cell); } if (cell.SQuery.Extent.Equals((object)this.ParentTable)) { cellList1.Add(cell); } } foreach (Cell cell1 in cellList2) { List <List <int> > slotNumsForColumns1 = ForeignConstraint.GetSlotNumsForColumns(cell1, this.ChildColumns); if (slotNumsForColumns1.Count != 0) { List <MemberPath> memberPathList1 = (List <MemberPath>)null; List <MemberPath> memberPathList2 = (List <MemberPath>)null; Cell cell2 = (Cell)null; foreach (List <int> intList1 in slotNumsForColumns1) { memberPathList1 = new List <MemberPath>(intList1.Count); foreach (int slotNum in intList1) { MemberProjectedSlot memberProjectedSlot = (MemberProjectedSlot)cell1.CQuery.ProjectedSlotAt(slotNum); memberPathList1.Add(memberProjectedSlot.MemberPath); } foreach (Cell cell3 in cellList1) { List <List <int> > slotNumsForColumns2 = ForeignConstraint.GetSlotNumsForColumns(cell3, this.ParentColumns); if (slotNumsForColumns2.Count != 0) { foreach (List <int> intList2 in slotNumsForColumns2) { memberPathList2 = new List <MemberPath>(intList2.Count); foreach (int slotNum in intList2) { MemberProjectedSlot memberProjectedSlot = (MemberProjectedSlot)cell3.CQuery.ProjectedSlotAt(slotNum); memberPathList2.Add(memberProjectedSlot.MemberPath); } if (memberPathList1.Count == memberPathList2.Count) { bool flag = false; for (int index = 0; index < memberPathList1.Count && !flag; ++index) { MemberPath memberPath = memberPathList2[index]; MemberPath path1 = memberPathList1[index]; if (!memberPath.LeafEdmMember.Equals((object)path1.LeafEdmMember)) { if (memberPath.IsEquivalentViaRefConstraint(path1)) { return(true); } flag = true; } } if (!flag) { return(true); } cell2 = cell3; } } } } } ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, Strings.ViewGen_Foreign_Key_ColumnOrder_Incorrect((object)this.ToUserString(), (object)MemberPath.PropertiesToUserString(this.ChildColumns, false), (object)this.ChildTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList1, false), (object)cell1.CQuery.Extent.Name, (object)MemberPath.PropertiesToUserString(this.ParentColumns, false), (object)this.ParentTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList2, false), (object)cell2.CQuery.Extent.Name), (IEnumerable <Cell>) new Cell[2] { cell2, cell1 }, string.Empty); errorLog.AddEntry(record); return(false); } } return(true); }
internal override bool VisitLeaf(LeafCellTreeNode node, bool dummy) { CellQuery rightCellQuery1 = this.m_wrapper.RightCellQuery; CellQuery rightCellQuery2 = node.LeftCellWrapper.RightCellQuery; List <MemberPath> memberPathList = new List <MemberPath>(); if (rightCellQuery1 != rightCellQuery2) { for (int slotNum = 0; slotNum < rightCellQuery1.NumProjectedSlots; ++slotNum) { MemberProjectedSlot memberProjectedSlot1 = rightCellQuery1.ProjectedSlotAt(slotNum) as MemberProjectedSlot; if (memberProjectedSlot1 != null) { MemberProjectedSlot memberProjectedSlot2 = rightCellQuery2.ProjectedSlotAt(slotNum) as MemberProjectedSlot; if (memberProjectedSlot2 != null) { MemberPath projectedSlot = this.m_viewgenContext.MemberMaps.ProjectedSlotMap[slotNum]; if (!projectedSlot.IsPartOfKey && !MemberPath.EqualityComparer.Equals(memberProjectedSlot1.MemberPath, memberProjectedSlot2.MemberPath)) { memberPathList.Add(projectedSlot); } } } } } if (memberPathList.Count > 0) { this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NonKeyProjectedWithOverlappingPartitions, Strings.ViewGen_NonKeyProjectedWithOverlappingPartitions((object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList, false)), (IEnumerable <LeftCellWrapper>) new LeftCellWrapper[2] { this.m_wrapper, node.LeftCellWrapper }, string.Empty)); } return(true); }
private void CheckConcurrencyControlTokens() { EntityTypeBase elementType = this.m_extent.ElementType; Set <EdmMember> forTypeHierarchy = MetadataHelper.GetConcurrencyMembersForTypeHierarchy(elementType, this.m_edmItemCollection); Set <MemberPath> other = new Set <MemberPath>(MemberPath.EqualityComparer); foreach (EdmMember member in forTypeHierarchy) { if (!member.DeclaringType.IsAssignableFrom((EdmType)elementType)) { ExceptionHelpers.ThrowMappingException(new ErrorLog.Record(ViewGenErrorCode.ConcurrencyDerivedClass, Strings.ViewGen_Concurrency_Derived_Class((object)member.Name, (object)member.DeclaringType.Name, (object)this.m_extent), (IEnumerable <LeftCellWrapper>) this.m_cellWrappers, string.Empty), this.m_config); } other.Add(new MemberPath(this.m_extent, member)); } if (forTypeHierarchy.Count <= 0) { return; } foreach (LeftCellWrapper cellWrapper in this.m_cellWrappers) { Set <MemberPath> set = new Set <MemberPath>(cellWrapper.OnlyInputCell.CQuery.WhereClause.MemberRestrictions.Select <MemberRestriction, MemberPath>((Func <MemberRestriction, MemberPath>)(oneOf => oneOf.RestrictedMemberSlot.MemberPath)), MemberPath.EqualityComparer); set.Intersect(other); if (set.Count > 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(Strings.ViewGen_Concurrency_Invalid_Condition((object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)set, false), (object)this.m_extent.Name)); ExceptionHelpers.ThrowMappingException(new ErrorLog.Record(ViewGenErrorCode.ConcurrencyTokenHasCondition, stringBuilder.ToString(), (IEnumerable <LeftCellWrapper>) new LeftCellWrapper[1] { cellWrapper }, string.Empty), this.m_config); } } }