Inheritance: BaseRegionIterator
Exemple #1
0
        private void SynchronizeRowFromRowElementEx(XmlBoundElement rowElement, ArrayList rowElemList)
        {
            Debug.Assert(rowElement != null);
            Debug.Assert(rowElement.Row != null);
            Debug.Assert(DataSet.EnforceConstraints == false);

            DataRow row = rowElement.Row;
            Debug.Assert(row != null);
            DataTable table = row.Table;

            Hashtable foundColumns = new Hashtable();
            string xsi_attrVal = string.Empty;

            RegionIterator iter = new RegionIterator(rowElement);
            bool fMore;
            // If present, fill up the TextOnly column
            DataColumn column = GetTextOnlyColumn(row);
            if (column != null)
            {
                foundColumns[column] = column;
                string value;
                fMore = iter.NextInitialTextLikeNodes(out value);
                if (value.Length == 0 && (((xsi_attrVal = rowElement.GetAttribute(XSI_NIL)) == "1") || xsi_attrVal == "true"))
                    row[column] = DBNull.Value;
                else
                    SetRowValueFromXmlText(row, column, value);
            }
            else
                fMore = iter.Next();

            // Fill up the columns mapped to an element
            while (fMore)
            {
                XmlElement e = iter.CurrentNode as XmlElement;
                if (e == null)
                {
                    fMore = iter.Next();
                    continue;
                }

                XmlBoundElement be = e as XmlBoundElement;
                if (be != null && be.Row != null)
                {
                    if (rowElemList != null)
                        rowElemList.Add(e);
                    // Skip over sub-regions
                    fMore = iter.NextRight();
                    continue;
                }

                DataColumn c = _mapper.GetColumnSchemaForNode(rowElement, e);
                if (c != null)
                {
                    Debug.Assert(c.Table == row.Table);
                    if (foundColumns[c] == null)
                    {
                        foundColumns[c] = c;
                        string value;
                        fMore = iter.NextInitialTextLikeNodes(out value);
                        if (value.Length == 0 && (((xsi_attrVal = e.GetAttribute(XSI_NIL)) == "1") || xsi_attrVal == "true"))
                            row[c] = DBNull.Value;
                        else
                            SetRowValueFromXmlText(row, c, value);
                        continue;
                    }
                }

                fMore = iter.Next();
            }

            //
            // Walk the attributes to find attributes that map to columns.
            //
            foreach (XmlAttribute attr in rowElement.Attributes)
            {
                DataColumn c = _mapper.GetColumnSchemaForNode(rowElement, attr);

                if (c != null)
                {
                    if (foundColumns[c] == null)
                    {
                        foundColumns[c] = c;
                        SetRowValueFromXmlText(row, c, attr.Value);
                    }
                }
            }

            // Null all columns values that aren't represented in the tree
            foreach (DataColumn c in row.Table.Columns)
            {
                if (foundColumns[c] == null && !IsNotMapped(c))
                {
                    if (!c.AutoIncrement)
                        SetRowValueToNull(row, c);
                    else
                        c.Init(row._tempRecord);
                }
            }
        }
Exemple #2
0
        // A row-elem was inserted into the connected tree (connected) from oldParent==null state
        private void OnRowElementInsertedInTree(XmlBoundElement rowElem, ArrayList rowElemList)
        {
            Debug.Assert(rowElem.Row != null);

            DataRow row = rowElem.Row;
            DataRowState rowState = row.RowState;

            switch (rowState)
            {
                case DataRowState.Detached:
#if DEBUG
                    try
                    {
                        Debug.Assert(row.Table.DataSet.EnforceConstraints == false);
#endif
                        row.Table.Rows.Add(row);
                        SetNestedParentRegion(rowElem);
#if DEBUG
                    }
                    catch
                    {
                        // We should not get any exceptions here
                        Debug.Assert(false);
                        throw;
                    }
#endif
                    // Add all sub-regions to the list if the caller needs this
                    if (rowElemList != null)
                    {
                        RegionIterator iter = new RegionIterator(rowElem);
                        for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement())
                            rowElemList.Add(iter.CurrentNode);
                    }
                    break;
                case DataRowState.Deleted:
#if DEBUG
                    try
                    {
                        Debug.Assert(row.Table.DataSet.EnforceConstraints == false);
#endif
                        // Change the row status to be alive (unchanged)
                        row.RejectChanges();
                        // Set ROM from XML
                        SynchronizeRowFromRowElement(rowElem, rowElemList);
                        // Set nested parent data row according to where is the row positioned in the tree
                        SetNestedParentRegion(rowElem);
#if DEBUG
                    }
                    catch
                    {
                        // We should not get any exceptions here
                        Debug.Assert(false);
                        throw;
                    }
#endif
                    break;
                default:
                    // Handle your case above
                    Debug.Assert(false);
                    break;
            }
            Debug.Assert(IsRowLive(rowElem.Row));
        }
Exemple #3
0
        private void OnColumnValueChanged(DataRow row, DataColumn col, XmlBoundElement rowElement)
        {
            if (IsNotMapped(col))
            {
                goto lblDoNestedRelationSync;
            }

            object value = row[col];

            if (col.ColumnMapping == MappingType.SimpleContent && Convert.IsDBNull(value) && !rowElement.IsFoliated)
            {
                ForceFoliation(rowElement, ElementState.WeakFoliation);
            }
            else
            {
                // no need to sync if not foliated
                if (!IsFoliated(rowElement))
                {
#if DEBUG
                    // If the new value is null, we should be already foliated if there is a DataPointer that points to the column
                    // (see OnRowChanging, case DataRowAction.Change)
                    if (Convert.IsDBNull(row[col, DataRowVersion.Current]))
                    {
                        try
                        {
                            if (_pointers.Count > 0)
                            {
                                object pointer = null;
                                foreach (DictionaryEntry entry in _pointers)
                                {
                                    pointer = entry.Value;
                                    Debug.Assert((pointer != null) && !((IXmlDataVirtualNode)pointer).IsOnColumn(col));
                                }
                            }
                        }
                        catch (Exception e) when (Data.Common.ADP.IsCatchableExceptionType(e))
                        {
                            // We may get an exception if we are in foreach and a new pointer has been added to this.pointers. When this happens, we will skip this check and ignore the exceptions
                        }
                    }
#endif
                    goto lblDoNestedRelationSync;
                }
            }

            if (IsTextOnly(col))
            {
                if (Convert.IsDBNull(value))
                {
                    value = string.Empty;
                    //make sure that rowElement has Attribute xsi:nil and its value is true
                    XmlAttribute attr = rowElement.GetAttributeNode(XSI_NIL);
                    if (attr == null)
                    {
                        attr = CreateAttribute(XSI, Keywords.XSI_NIL, Keywords.XSINS);
                        attr.Value = Keywords.TRUE;
                        rowElement.SetAttributeNode(attr);
                        _bHasXSINIL = true;
                    }
                    else
                        attr.Value = Keywords.TRUE;
                }
                else
                {
                    //make sure that if rowElement has Attribute xsi:nil, its value is false
                    XmlAttribute attr = rowElement.GetAttributeNode(XSI_NIL);
                    if (attr != null)
                        attr.Value = Keywords.FALSE;
                }
                ReplaceInitialChildText(rowElement, col.ConvertObjectToXml(value));
                goto lblDoNestedRelationSync;
            }

            // update the attribute that maps to the column
            bool fFound = false;

            // Find the field node and set it's value
            if (col.ColumnMapping == MappingType.Attribute)
            {
                foreach (XmlAttribute attr in rowElement.Attributes)
                {
                    if (attr.LocalName == col.EncodedColumnName && attr.NamespaceURI == col.Namespace)
                    {
                        if (Convert.IsDBNull(value))
                        {
                            attr.OwnerElement.Attributes.Remove(attr);
                        }
                        else
                        {
                            attr.Value = col.ConvertObjectToXml(value);
                        }
                        fFound = true;
                        break;
                    }
                }

                // create new attribute if we didn't find one.
                if (!fFound && !Convert.IsDBNull(value))
                {
                    rowElement.SetAttribute(col.EncodedColumnName, col.Namespace, col.ConvertObjectToXml(value));
                }
            }
            else
            {
                // update elements that map to the column...
                RegionIterator iter = new RegionIterator(rowElement);
                bool fMore = iter.Next();
                while (fMore)
                {
                    if (iter.CurrentNode.NodeType == XmlNodeType.Element)
                    {
                        XmlElement e = (XmlElement)iter.CurrentNode;
                        Debug.Assert(e != null);
                        //we should skip the subregion
                        XmlBoundElement be = e as XmlBoundElement;
                        if (be != null && be.Row != null)
                        {
                            fMore = iter.NextRight(); //skip over the sub-region
                            continue;
                        }
                        if (e.LocalName == col.EncodedColumnName && e.NamespaceURI == col.Namespace)
                        {
                            fFound = true;
                            if (Convert.IsDBNull(value))
                            {
                                PromoteNonValueChildren(e);
                                fMore = iter.NextRight();
                                e.ParentNode.RemoveChild(e);
                                // keep looking for more matching elements
                                continue;
                            }
                            else
                            {
                                ReplaceInitialChildText(e, col.ConvertObjectToXml(value));
                                //make sure that if the Element has Attribute xsi:nil, its value is false
                                XmlAttribute attr = e.GetAttributeNode(XSI_NIL);
                                if (attr != null)
                                    attr.Value = Keywords.FALSE;
                                // no need to look any further.
                                goto lblDoNestedRelationSync;
                            }
                        }
                    }
                    fMore = iter.Next();
                }

                // create new element if we didn't find one.
                if (!fFound && !Convert.IsDBNull(value))
                {
                    XmlElement newElem = new XmlBoundElement(string.Empty, col.EncodedColumnName, col.Namespace, this);
                    newElem.AppendChild(CreateTextNode(col.ConvertObjectToXml(value)));

                    XmlNode elemBefore = GetColumnInsertAfterLocation(row, col, rowElement);
                    if (elemBefore != null)
                    {
                        rowElement.InsertAfter(newElem, elemBefore);
                    }
                    else if (rowElement.FirstChild != null)
                    {
                        rowElement.InsertBefore(newElem, rowElement.FirstChild);
                    }
                    else
                    {
                        rowElement.AppendChild(newElem);
                    }
                }
            }
        lblDoNestedRelationSync:
            // Change the XML to conform to the (potentially) change in parent nested relation
            DataRelation relation = GetNestedParentRelation(row);
            if (relation != null)
            {
                Debug.Assert(relation.ChildTable == row.Table);
                if (relation.ChildKey.ContainsColumn(col))
                    OnNestedParentChange(row, rowElement, col);
            }
        }