private static void CopyToRow(BaseTypedDictionary dictionary, DataRow row) { foreach (KeyValuePair <string, object> kvp in dictionary) { DataColumn col = row.Table.Columns[kvp.Key]; if ((col != null) && !col.ReadOnly && !col.AutoIncrement) { row[col] = kvp.Value; } } }
private static DataRow FindRow(BaseTypedDictionary row, DataTable table) { DataColumn[] tableKeys = table.PrimaryKey; object[] rowKeys = new object[tableKeys.Length]; for (int i = 0; i < tableKeys.Length; i++) { DataColumn tableKey = tableKeys[i]; string keyName = tableKey.ColumnName; rowKeys[i] = row[keyName]; } return(table.Rows.Find(rowKeys)); }
/// <summary> /// Invokes a method on an object by dynamically constructing its argument list. /// </summary> /// <param name="method">The method to invoke.</param> /// <param name="target">The target of the method invocation.</param> /// <param name="parameter">An object or IDictionary that describes the method parameters.</param> /// <returns>The return value of the method.</returns> private static object InvokeMethod(MethodInfo method, object target, object parameter) { ParameterInfo[] targetMethodParameters = method.GetParameters(); object[] parameterValues = new object[targetMethodParameters.Length]; if (targetMethodParameters.Length > 0) { if (parameter == null) { throw new ArgumentNullException("parameter"); } if (targetMethodParameters.Length == 1) { Type parameterType = targetMethodParameters[0].ParameterType; if (parameterType.IsAssignableFrom(parameter.GetType())) { // 1. There is one destination parameter whose type is directly compatible with the parameter we have parameterValues[0] = parameter; } else { // Create a dictionary from the parameter BaseTypedDictionary parameterDictionary = GetDictionary(parameter, targetMethodParameters); object value; if (parameterDictionary.TryGetValue(targetMethodParameters[0].Name, out value)) { // 2. There is one destination parameter whose name exists in our parameter dictionary parameterValues[0] = value; } else { // 3. There is one destination parameter with a complex type of which we must reconstruct // an instance from the dictionary // Construct the instance object parameterValue = Activator.CreateInstance(parameterType); // Copy property values from dictionary entries // DataService does NOT support fields because DataObjectFieldAttribute // can't be applied to fields. // DataService implementations that use the attributes won't be able to use fields // and implementations that don't won't use InvokeMethod. foreach (KeyValuePair <string, object> entry in parameterDictionary) { PropertyInfo propertyInfo = GetPropertyInfo(parameterType, entry.Key); if (propertyInfo != null && propertyInfo.CanWrite) { propertyInfo.SetValue(parameterValue, entry.Value, null); } } parameterValues[0] = parameterValue; } } } else { // 4. There are multiple simple type parameters that we copy from the parameter dictionary BaseTypedDictionary parameterDictionary = GetDictionary(parameter, targetMethodParameters); for (int i = 0; i < targetMethodParameters.Length; i++) { ParameterInfo parameterInfo = targetMethodParameters[i]; object value; if (parameterDictionary.TryGetValue(parameterInfo.Name, out value)) { parameterValues[i] = value; } else { throw new InvalidOperationException(); } } } } return(method.Invoke(target, parameterValues)); }
protected virtual DataTable SaveDataImplementation(ChangeList changeList, object parameters, string loadMethod) { if ((_adapter != null) && (_updateMethod != null)) { DataTable dataTable = GetData(parameters, loadMethod); foreach (object rowToDelete in changeList.Deleted) { FindRow(GetDictionary(rowToDelete, dataTable.Columns), dataTable).Delete(); } foreach (object rowToUpdate in changeList.Updated) { BaseTypedDictionary rowDict = GetDictionary(rowToUpdate, dataTable.Columns); DataRow tableRow = FindRow(rowDict, dataTable); CopyToRow(rowDict, tableRow); } foreach (object rowToInsert in changeList.Inserted) { DataRow newRow = dataTable.NewRow(); dataTable.Rows.Add(newRow); BaseTypedDictionary rowDict = GetDictionary(rowToInsert, dataTable.Columns); CopyToRow(rowDict, newRow); } _updateMethod.Invoke(_adapter, new object[] { dataTable }); return(dataTable); } else { MethodInfo deleteMethod = GetDataMethod(DataObjectMethodType.Delete); MethodInfo updateMethod = GetDataMethod(DataObjectMethodType.Update); MethodInfo insertMethod = GetDataMethod(DataObjectMethodType.Insert); if (deleteMethod != null) { foreach (object rowToDelete in changeList.Deleted) { InvokeMethod(deleteMethod, this, rowToDelete); } } else if (changeList.Deleted.Length != 0) { throw new InvalidOperationException("The Data Service must implement one method marked with the DataObjectMethod(DataObjectMethodType.Delete) attribute to handle deleted rows."); } if (updateMethod != null) { foreach (object rowToUpdate in changeList.Updated) { InvokeMethod(updateMethod, this, rowToUpdate); } } else if (changeList.Updated.Length != 0) { throw new InvalidOperationException("The Data Service must implement one method marked with the DataObjectMethod(DataObjectMethodType.Update) attribute to handle updated rows."); } if (insertMethod != null) { foreach (object rowToInsert in changeList.Inserted) { InvokeMethod(insertMethod, this, rowToInsert); } } else if (changeList.Inserted.Length != 0) { throw new InvalidOperationException("The Data Service must implement one method marked with the DataObjectMethod(DataObjectMethodType.Insert) attribute to handle inserted rows."); } return(GetData(parameters, loadMethod)); } }