如何将 class 上的属性设置为与类型匹配的方法组列表?
How to set properties on a class to a list of method groups matching on type?
我们之前拥有的是要向其添加参数的 OracleCommand,然后我们在其上 运行 ExecuteReaderAsync 以获得 OracleDataReader。然后我们通过调用一个 "GetList" 方法来填充不同对象的列表,该方法将采用 reader 和一个方法组,该方法组 returns 一个与列表相同类型的对象。
// These parameters need to be in the same order as returned by the procedure.
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("ProcedureTable1", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.Add("ProcedureTable2", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.Add("ProcedureTable3", OracleDbType.RefCursor, ParameterDirection.Output);
OracleDataReader reader = await command.ExecuteReaderAsync() as OracleDataReader;
// These methods need to be called in the same order as the parameters above.
List<Type1> type1s = await GetList(reader, CreateType1, false); // The first item is called with an overload that takes wht
List<Type2> type2s = await GetList(reader, CreateType2);
List<Type3> type3s = await GetList(reader, CreateType3);
正如建议所暗示的那样,问题是如果参数乱序,我们将得到数据库异常而不是数据。如果对方法组的调用被乱序放置,列表将简单地填充它们应该包含的 class 的空版本。
建议使用有序列表,所以我设置了一个Dictionary来保存DataPackage对象,其中包含数据库包和方法组中过程的字符串名称。
我很容易就能按正确的顺序将它们全部添加一次,并设置命令参数。
// These parameter/method pairs need to be in the same order as returned by the procedure.
List<DataPackage> orderedList = new List<DataPackage>
{
new DataPackage<Type1>("Type1ProcedureName", CreateType1MethodGroup, type1List),
new DataPackage<Type2>("Type2ProcedureName", CreateType2MethodGroup, type2List),
new DataPackage<Type3>("Type3ProcedureName", CreateType3MethodGroup, type1List),
};
command.CommandType = CommandType.StoredProcedure;
orderedList.ForEach(p => command.Parameters.Add(p.ProcedureName, OracleDbType.RefCursor, ParameterDirection.Output));
随着 classes
public class DataPackage
{
public string ProcedureName { get; protected set; }
public Func<OracleDataReader, object> MethodGroup { get; protected set; }
public virtual void Add(object list)
{
}
}
和
public class DataPackage<T> : DataPackage
{
public DataPackage(string procedureName, Func<OracleDataReader, object> methodGroup, List<T> returnedData)
{
this.ProcedureName = procedureName;
this.MethodGroup = methodGroup;
this.ReturnedData = returnedData;
}
public List<T> ReturnedData { get; set; }
public override void Add (object list)
{
List<T> castList = list as List<T>;
if (castList != null)
{
this.ReturnedData.AddRange(castList);
}
}
}
至少按顺序添加一次就可以了。我无法弄清楚的部分是用每个方法组调用 GetList 来填充数据。
orderedList.ForEach(async v =>
{
v.Add(await GetList(reader, v.MethodGroup, false));
});
问题是当我在 DataPackage 上调试 Add 方法时,列表作为一个对象出现,它试图转换为 List 但失败了,即使 list 参数显然是一个列表并且充满了数据.
有更好的方法吗?
我正在搜索并找到问题 Cast Object to Generic List 并将类型化 DataPackage 的 Add 方法中的代码更改为
public override void Add (object list)
{
IEnumerable castList = list as IEnumerable;
if (castList != null)
{
IEnumerable<T> typedList = castList.OfType<T>();
this.ReturnedData.AddRange(typedList);
}
}
而且效果很好。
我们之前拥有的是要向其添加参数的 OracleCommand,然后我们在其上 运行 ExecuteReaderAsync 以获得 OracleDataReader。然后我们通过调用一个 "GetList" 方法来填充不同对象的列表,该方法将采用 reader 和一个方法组,该方法组 returns 一个与列表相同类型的对象。
// These parameters need to be in the same order as returned by the procedure.
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("ProcedureTable1", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.Add("ProcedureTable2", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.Add("ProcedureTable3", OracleDbType.RefCursor, ParameterDirection.Output);
OracleDataReader reader = await command.ExecuteReaderAsync() as OracleDataReader;
// These methods need to be called in the same order as the parameters above.
List<Type1> type1s = await GetList(reader, CreateType1, false); // The first item is called with an overload that takes wht
List<Type2> type2s = await GetList(reader, CreateType2);
List<Type3> type3s = await GetList(reader, CreateType3);
正如建议所暗示的那样,问题是如果参数乱序,我们将得到数据库异常而不是数据。如果对方法组的调用被乱序放置,列表将简单地填充它们应该包含的 class 的空版本。
建议使用有序列表,所以我设置了一个Dictionary来保存DataPackage对象,其中包含数据库包和方法组中过程的字符串名称。
我很容易就能按正确的顺序将它们全部添加一次,并设置命令参数。
// These parameter/method pairs need to be in the same order as returned by the procedure.
List<DataPackage> orderedList = new List<DataPackage>
{
new DataPackage<Type1>("Type1ProcedureName", CreateType1MethodGroup, type1List),
new DataPackage<Type2>("Type2ProcedureName", CreateType2MethodGroup, type2List),
new DataPackage<Type3>("Type3ProcedureName", CreateType3MethodGroup, type1List),
};
command.CommandType = CommandType.StoredProcedure;
orderedList.ForEach(p => command.Parameters.Add(p.ProcedureName, OracleDbType.RefCursor, ParameterDirection.Output));
随着 classes
public class DataPackage
{
public string ProcedureName { get; protected set; }
public Func<OracleDataReader, object> MethodGroup { get; protected set; }
public virtual void Add(object list)
{
}
}
和
public class DataPackage<T> : DataPackage
{
public DataPackage(string procedureName, Func<OracleDataReader, object> methodGroup, List<T> returnedData)
{
this.ProcedureName = procedureName;
this.MethodGroup = methodGroup;
this.ReturnedData = returnedData;
}
public List<T> ReturnedData { get; set; }
public override void Add (object list)
{
List<T> castList = list as List<T>;
if (castList != null)
{
this.ReturnedData.AddRange(castList);
}
}
}
至少按顺序添加一次就可以了。我无法弄清楚的部分是用每个方法组调用 GetList 来填充数据。
orderedList.ForEach(async v =>
{
v.Add(await GetList(reader, v.MethodGroup, false));
});
问题是当我在 DataPackage 上调试 Add 方法时,列表作为一个对象出现,它试图转换为 List 但失败了,即使 list 参数显然是一个列表并且充满了数据. 有更好的方法吗?
我正在搜索并找到问题 Cast Object to Generic List 并将类型化 DataPackage 的 Add 方法中的代码更改为
public override void Add (object list)
{
IEnumerable castList = list as IEnumerable;
if (castList != null)
{
IEnumerable<T> typedList = castList.OfType<T>();
this.ReturnedData.AddRange(typedList);
}
}
而且效果很好。