将 DataRow 转换为单个对象 - 类型约束
Converting a DataRow to a single object - type constraints
我有以下实现可用于将 DataTable
中的行转换为 List<T>
。 IDataItem
接口仅包含接受单个 DataRow
对象的 SetData
方法。
public class GroupedData<T> : List<T> where T : IDataItem, new()
{
public GroupedData(DataTable table)
{
for (int i = 0; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
var newItem = new T();
newItem.SetData(row);
Add(newItem);
}
}
}
这些是 class 中的属性 我正在尝试将值分配给:
public class Details
{
public List<AuditData> AuditEntries { get; set; }
public AuditMethodSummaryData AuditMethodSummaryData { get; set; }
}
使用 GroupedData class,我可以执行以下操作来填充 AuditEntries:
var returnData = new Details();
returnData.AuditEntries = new GroupedData<AuditData>(dataSet.Tables[TableNames.AuditDetails]);
对于第二个 属性,AuditMethodSummaryData。我需要分配单个对象而不是列表。我不知道如何创建另一个可以执行该功能的 class。
注意 - 我仍然需要传入一个数据表。但是,数据 table 只会包含一行(由于系统的工作方式)。
我想到的唯一解决方案如下。我只是想看看有没有更好的解决办法:
public class SingleData
{
public static T GetItem<T>(DataTable table) where T : IDataItem, new()
{
if (table.Rows.Count >= 1)
{
DataRow row = table.Rows[0];
var newItem = new T();
newItem.SetData(row);
}
}
}
我不喜欢的是我已将约束从 class 移至方法。有什么办法可以将它保留在 class 上吗?避免使用静态方法。
好吧,对于单个项目,您根本不需要泛型:
public class SingleItem : IDataItem
{
public SingleItem(DataTable table)
{
if (table.Rows.Count >= 1)
{
var row = table.Rows[0];
SetData(row);
}
else
{
throw new ArgumentException("No rows.", "table");
}
}
public abstract void SetData(DataRow row);
}
public AuditMethodSummaryData : SingleItem
{
public AuditMethodSummaryData(DataTable table) : base(table)
{}
public override void SetData(DataRow row) { /*...*/ }
}
当您需要 return null
零行时,这仍然无法解决问题。在那种情况下,您必须使用工厂模式——可以通过多种方式实现——静态方法是简单的,我认为适合您的情况;如果您不想使用静态方法,则必须创建工厂 class 而不是:
public class DataItemFactory<T> where T : IDataItem, new()
{
private readonly DataTable m_Table;
public DataItemFactory(DataTable table)
{
m_Table = table;
}
public T Create()
{
T result = default(T);
if (m_Table.Rows.Count > 1)
{
result = new T();
result.SetData(m_Table.Rows[0]);
}
return result;
}
}
用法如下:
returnData.AuditMethodSummaryData =
new DataItemFactory<AuditMethodSummaryData>(table).Create();
我有以下实现可用于将 DataTable
中的行转换为 List<T>
。 IDataItem
接口仅包含接受单个 DataRow
对象的 SetData
方法。
public class GroupedData<T> : List<T> where T : IDataItem, new()
{
public GroupedData(DataTable table)
{
for (int i = 0; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
var newItem = new T();
newItem.SetData(row);
Add(newItem);
}
}
}
这些是 class 中的属性 我正在尝试将值分配给:
public class Details
{
public List<AuditData> AuditEntries { get; set; }
public AuditMethodSummaryData AuditMethodSummaryData { get; set; }
}
使用 GroupedData class,我可以执行以下操作来填充 AuditEntries:
var returnData = new Details();
returnData.AuditEntries = new GroupedData<AuditData>(dataSet.Tables[TableNames.AuditDetails]);
对于第二个 属性,AuditMethodSummaryData。我需要分配单个对象而不是列表。我不知道如何创建另一个可以执行该功能的 class。
注意 - 我仍然需要传入一个数据表。但是,数据 table 只会包含一行(由于系统的工作方式)。
我想到的唯一解决方案如下。我只是想看看有没有更好的解决办法:
public class SingleData
{
public static T GetItem<T>(DataTable table) where T : IDataItem, new()
{
if (table.Rows.Count >= 1)
{
DataRow row = table.Rows[0];
var newItem = new T();
newItem.SetData(row);
}
}
}
我不喜欢的是我已将约束从 class 移至方法。有什么办法可以将它保留在 class 上吗?避免使用静态方法。
好吧,对于单个项目,您根本不需要泛型:
public class SingleItem : IDataItem
{
public SingleItem(DataTable table)
{
if (table.Rows.Count >= 1)
{
var row = table.Rows[0];
SetData(row);
}
else
{
throw new ArgumentException("No rows.", "table");
}
}
public abstract void SetData(DataRow row);
}
public AuditMethodSummaryData : SingleItem
{
public AuditMethodSummaryData(DataTable table) : base(table)
{}
public override void SetData(DataRow row) { /*...*/ }
}
当您需要 return null
零行时,这仍然无法解决问题。在那种情况下,您必须使用工厂模式——可以通过多种方式实现——静态方法是简单的,我认为适合您的情况;如果您不想使用静态方法,则必须创建工厂 class 而不是:
public class DataItemFactory<T> where T : IDataItem, new()
{
private readonly DataTable m_Table;
public DataItemFactory(DataTable table)
{
m_Table = table;
}
public T Create()
{
T result = default(T);
if (m_Table.Rows.Count > 1)
{
result = new T();
result.SetData(m_Table.Rows[0]);
}
return result;
}
}
用法如下:
returnData.AuditMethodSummaryData =
new DataItemFactory<AuditMethodSummaryData>(table).Create();