using EasyDevCore.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EasyDevCore.Database.EntityTable
{
///
///
///
public static class DataRowExtensions
{
///
/// Gets a value indicating whether this instance is new.
///
///
/// true if this instance is new; otherwise, false.
///
public static bool IsNew(this DataRow row) => row.RowState == DataRowState.Added;
///
/// Gets a value indicating whether this instance is deleted.
///
///
/// true if this instance is new; otherwise, false.
///
public static bool IsDeleted(this DataRow row) => row.RowState == DataRowState.Deleted;
///
/// Gets a value indicating whether this instance is changed.
///
///
/// true if this instance is changed; otherwise, false.
///
public static bool IsChanged(this DataRow row) => row.RowState == DataRowState.Added || row.RowState == DataRowState.Deleted || row.RowState == DataRowState.Modified;
///
/// Determines whether the specified column index is changed.
///
/// The row.
/// Index of the column.
///
/// true if the specified column index is changed; otherwise, false.
///
public static bool IsChanged(this DataRow row, int columnIndex)
{
var curValue = row.HasVersion(DataRowVersion.Current) ? row[columnIndex, DataRowVersion.Current] : null;
var oldValue = row.HasVersion(DataRowVersion.Original) ? row[columnIndex, DataRowVersion.Original] : null;
if (oldValue != null && curValue == null || oldValue == null && curValue != null
|| oldValue != curValue)
{
return true;
}
return false;
}
///
/// Determines whether the specified column name is changed.
///
/// The row.
/// Name of the column.
///
/// true if the specified column name is changed; otherwise, false.
///
public static bool IsChanged(this DataRow row, string columnName)
{
var curValue = row.HasVersion(DataRowVersion.Current) ? row[columnName, DataRowVersion.Current] : null;
var oldValue = row.HasVersion(DataRowVersion.Original) ? row[columnName, DataRowVersion.Original] : null;
if (oldValue != null && curValue == null || oldValue == null && curValue != null
|| oldValue != curValue)
{
return true;
}
return false;
}
/// Gets the value, if value = DBNull.Value, return null value
///
/// Index of the column.
///
///
public static object GetValue(this DataRow row, int columnIndex) => row[columnIndex] == DBNull.Value ? null : row[columnIndex];
///
/// Gets the value, if value = DBNull.Value, return null value
///
/// The row.
/// Name of the column.
///
public static object GetValue(this DataRow row, string columnName) => row[columnName] == DBNull.Value ? null : row[columnName];
///
/// Gets the value, if value = DBNull.Value, return valueIfNull value
///
///
/// The row.
/// Index of the column.
/// The value if null.
///
public static T GetValue(this DataRow row, int columnIndex, T valueIfNull = default) => row[columnIndex] == DBNull.Value ? valueIfNull : (T)row[columnIndex];
///
/// Gets the value, if value = DBNull.Value, return valueIfNull value
///
///
/// The row.
/// Name of the column.
/// The value if null.
///
public static T GetValue(this DataRow row, string columnName, T valueIfNull = default) => row[columnName] == DBNull.Value ? valueIfNull : (T)row[columnName];
///
/// Sets the value.
///
/// The row.
/// Index of the column.
/// The value.
///
public static bool SetValue(this DataRow row, int columnIndex, object value)
{
object oldValue = row[columnIndex];
bool newValueIsNull = value == null || value.Equals(DBNull.Value);
bool oldValueIsNull = oldValue == DBNull.Value;
if (!newValueIsNull || !oldValueIsNull)
{
if (newValueIsNull)
{
row[columnIndex] = DBNull.Value;
return true;
}
if (oldValueIsNull || !value.Equals(oldValue))
{
row[columnIndex] = value;
return true;
}
}
return false;
}
///
/// Sets the value.
///
/// The row.
/// Name of the column.
/// The value.
///
public static bool SetValue(this DataRow row, string columnName, object value) => row.SetValue(row.Table.Columns[columnName].Ordinal, value);
///
/// Deletes the specified source.
///
/// The type of the source.
/// The source.
///
public static int Delete(this IEnumerable source)
where TSource : DataRow
{
int rowsEffected = 0;
foreach (var row in source)
{
row.Delete();
rowsEffected++;
}
return rowsEffected;
}
///
/// Updates the DataRow.
///
/// The type of the source.
/// The source.
/// The values.
///
/// string.Format("Invalid column name [{0}]", kp.Key)
public static TSource Update(this TSource source, params object[] values)
where TSource : DataRow
{
var args = ArgumentHelper.GetArgValues(values);
var table = source.Table;
foreach (var kp in args)
{
int colIndex = table.Columns.IndexOf(kp.Key);
if (colIndex >= 0)
{
source.SetValue(colIndex, kp.Value);
}
else
{
throw new Exception(string.Format("Invalid column name [{0}]", kp.Key));
}
}
return source;
}
///
/// Updates this instance with the values of the data row
///
/// The data row.
/// The source.
/// The colum names filter (can be use = for mapping; ex: ColumnName = PropertyName).
/// The except column names (splits by comma).
///
public static DataRow UpdateFrom(this DataRow row, DataRow source, string columnNames = "", string exceptColumnNames = "")
{
IDictionary listColumns = row.Table.GetMatchedColumnsList(source.Table, columnNames, exceptColumnNames);
foreach (var map in listColumns)
{
row[map.Key] = source[map.Value];
}
return row;
}
///
/// Updates this row with the values of the row view
///
/// The row.
/// The row view.
/// The colum names filter (can be use = for mapping; ex: ColumnName = PropertyName).
/// The except column names (splits by comma).
///
public static DataRow UpdateFrom(this DataRow row, DataRowView source, string columnNames = "", string exceptColumnNames = "")
{
IDictionary listColumns = row.Table.GetMatchedColumnsList(source.Row.Table, columnNames, exceptColumnNames);
foreach (var map in listColumns)
{
row[map.Key] = source[map.Value];
}
return row;
}
///
/// Updates to model.
///
///
/// The source.
/// The model.
/// The list properties.
/// The model status field.
internal static void UpdateToModel(this DataRow source, T model, IDictionary listProperties, string modelStatusField = "")
{
string propName = string.Empty;
try
{
foreach (var prop in listProperties)
{
PropertyDescriptor p = prop.Value;
p.SetValue(model, source[prop.Key]);
}
}
catch (Exception ex)
{
ex.Data["PropertyName"] = propName;
throw;
}
if (!string.IsNullOrWhiteSpace(modelStatusField)) model.SetPropertyValue(modelStatusField, source.RowState);
}
///
/// Converts to model.
///
///
/// The source.
/// The list properties.
/// The model status field has receive status of source (field type must be DataRowState).
/// The method.
///
internal static T ConvertToModel(this DataRow source, IDictionary listProperties, string modelStatusField = "", Action method = null)
{
T item = default;
item = Activator.CreateInstance();
source.UpdateToModel(item, listProperties, modelStatusField);
if (method != null) method(item);
return item;
}
///
/// Convert to Model DataRow.
///
///
/// The source.
/// The colum names filter (can be use = for mapping; ex: ColumnName = PropertyName).
/// The except column names.
/// The model status field has receive status of source (field type must be DataRowState).
/// The ignore prefix for ignore prefix characters when mapping field name with column name.
/// The method.
/// T.
public static T ConvertToModel(this DataRow source, string columnNames = "", string exceptColumnNames = "", string modelStatusField = "", string ignorePrefix = "", Action method = null)
{
Type DataRowType = typeof(T);
IDictionary properties = (source.Table as DataTable).GetMatchedPropertiesList(columnNames, exceptColumnNames, ignorePrefix);
T item = source.ConvertToModel(properties, modelStatusField);
if (method != null) method(item);
return item;
}
///
/// Updates from model.
///
///
/// The source.
/// The item.
/// The list properties.
internal static void UpdateFromModel(this DataRow source, T item, IDictionary listProperties)
{
string propName = string.Empty;
try
{
foreach (var prop in listProperties)
{
PropertyDescriptor p = prop.Value;
propName = prop.Key;
source[propName] = p.GetValue(item);
}
}
catch (Exception ex)
{
ex.Data["PropertyName"] = propName;
throw;
}
}
///
/// Updates from Model DataRow.
///
///
/// The source.
/// The item.
/// The colum names filter (can be use = for mapping; ex: ColumnName = PropertyName).
/// The except column names.
public static void UpdateFromModel(this DataRow source, T item, string columnNames = "", string exceptColumnNames = "")
{
IDictionary properties = (source.Table as DataTable).GetMatchedPropertiesList(columnNames, exceptColumnNames);
source.UpdateFromModel(item, properties);
}
///
/// Updates to model.
///
///
/// The source.
/// The model.
/// The colum names filter (can be use = for mapping; ex: ColumnName = PropertyName).
/// The except column names.
/// The model status field.
public static void UpdateToModel(this DataRow source, T model, string columnNames = "", string exceptColumnNames = "", string modelStatusField = "")
{
IDictionary properties = (source.Table as DataTable).GetMatchedPropertiesList(columnNames, exceptColumnNames);
source.UpdateToModel(model, properties, modelStatusField);
}
}
}