/// <summary> /// Exports the data object property values and child object values /// to the given data contract object by setting the specified properties /// of the data contract to the values of the corresponding properties /// or child objects with the same names. /// This method can be used to partially export data object values /// to a data contract object. /// </summary> /// <param name="dataContract">The data contract object to export /// the current data object values to.</param> /// <param name="props">The data contract object fields to set.</param> /// <param name="options">Additional options for the operation.</param> /// <param name="row">The data row context, if any.</param> protected void ToDataContractProperties(object dataContract, PropertyInfo[] props, object options, DataRow row = null) { if (dataContract == null) { return; } foreach (PropertyInfo pi in props) { DataProperty dp = this[pi.Name]; if (dp != null) { if (dp.IsValid(true, row)) { if (dp.IsMultiValued) { IList lst = null; if (dp.GetValue(ValueFormat.Transport, row) is IEnumerable valLst) { // create the right type of list and copy the values rather than directly assign lst = CreateInstance(pi.PropertyType) as IList; if (lst != null) { foreach (object o in valLst) { lst.Add(o); } } } pi.SetValue(dataContract, lst, null); } else { pi.SetValue(dataContract, dp.GetValue(ValueFormat.Transport, row), null); } } continue; } object obj; try { obj = CreateInstance(pi.PropertyType); } catch { continue; } DataObject child = GetChildObject(pi.Name); if (child != null) { child.ToDataContract(obj, options); } else { foreach (PropertyInfo cpi in pi.PropertyType.GetProperties()) { DataProperty cdp = this[pi.Name + "_" + cpi.Name]; if (cdp != null && cdp.IsValid(true, row)) { cpi.SetValue(obj, cdp.GetValue(ValueFormat.Transport, row), null); } } } pi.SetValue(dataContract, obj, null); } }
/// <summary> /// A filtering function that determines if the value of the specified property in the given row /// matches the specified criteria value using supplied operator. /// </summary> /// <param name="property">The data property of the object to match.</param> /// <param name="row">The data row to get the value from.</param> /// <param name="oper">Comparison operator to use.</param> /// <param name="criteria">The value to compare to.</param> /// <param name="caseSensitive">True to perform case-sensitive string matching, false otherwise.</param> /// <returns>True if the property value in the given row matches the specified criteria, false otherwise.</returns> public virtual bool PropertyValueMatches(DataProperty property, DataRow row, Operator oper, object criteria, bool caseSensitive) { ValueFormat format = criteria?.GetType() == typeof(string) ? ValueFormat.DisplayString : ValueFormat.Internal; object value = property.GetValue(format, row); criteria = property.ResolveValue(criteria, format); if (format.IsString() && !caseSensitive) { value = value?.ToString()?.ToLower(); criteria = criteria?.ToString()?.ToLower(); } return(oper.Matches(value, criteria)); }