private void ForceFoliation(XmlBoundElement node, ElementState newState)
{
lock (_foliationLock)
{
if (node.ElementState != ElementState.Defoliated)
// The region was foliated by an other thread while this thread was locked
return;
// Node must be a row-elem associated w/ a non-deleted row
Debug.Assert(node.Row != null);
Debug.Assert(node.Row.RowState != DataRowState.Deleted);
node.ElementState = ElementState.Foliating;
bool saveIgnore = IgnoreXmlEvents;
IgnoreXmlEvents = true;
try
{
XmlNode priorNode = null;
DataRow row = node.Row;
// create new attrs & elements for row
// For detached rows: we are in sync w/ temp values
// For non-detached rows: we are in sync w/ the current values
// For deleted rows: we never sync
DataRowVersion rowVersion = (row.RowState == DataRowState.Detached) ? DataRowVersion.Proposed : DataRowVersion.Current;
foreach (DataColumn col in row.Table.Columns)
{
if (!IsNotMapped(col))
{
object value = row[col, rowVersion];
if (!Convert.IsDBNull(value))
{
if (col.ColumnMapping == MappingType.Attribute)
{
node.SetAttribute(col.EncodedColumnName, col.Namespace, col.ConvertObjectToXml(value));
}
else
{
XmlNode newNode = null;
if (col.ColumnMapping == MappingType.Element)
{
newNode = new XmlBoundElement(string.Empty, col.EncodedColumnName, col.Namespace, this);
newNode.AppendChild(CreateTextNode(col.ConvertObjectToXml(value)));
if (priorNode != null)
{
node.InsertAfter(newNode, priorNode);
}
else if (node.FirstChild != null)
{
node.InsertBefore(newNode, node.FirstChild);
}
else
{
node.AppendChild(newNode);
}
priorNode = newNode;
}
else
{
Debug.Assert(col.ColumnMapping == MappingType.SimpleContent);
newNode = CreateTextNode(col.ConvertObjectToXml(value));
if (node.FirstChild != null)
node.InsertBefore(newNode, node.FirstChild);
else
node.AppendChild(newNode);
if (priorNode == null)
priorNode = newNode;
}
}
}
else
{
if (col.ColumnMapping == MappingType.SimpleContent)
{
XmlAttribute attr = CreateAttribute(XSI, Keywords.XSI_NIL, Keywords.XSINS);
attr.Value = Keywords.TRUE;
node.SetAttributeNode(attr);
_bHasXSINIL = true;
}
}
}
}
}
finally
{
IgnoreXmlEvents = saveIgnore;
node.ElementState = newState;
}
// update all live pointers
OnFoliated(node);
}
}