如何将类的属性设置为匹配类型的方法组列表?

时间:2017-06-07 21:12:08

标签: c# linq method-group

我们之前有一个OracleCommand,我们正在添加参数,然后我们在其上运行ExecuteReaderAsync来获取OracleDataReader。然后我们通过调用“GetList”方法来填充不同对象的列表,该方法将使读者和方法组返回与列表相同类型的对象。

// 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);

正如评论所暗示的那样,问题是如果参数不按顺序排列,我们会得到数据库异常而不是数据。如果对方法组的调用不按顺序排列,则列表只需填充它们应包含的类的空版本。

建议使用有序列表,因此我设置了一个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));

使用课程

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参数显然是一个列表并且填充了数据。 有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我正在搜索并找到问题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);
        }
    }

它运作正常。