如何在DNN中正确实现IHydratable接口?

时间:2010-08-26 20:04:08

标签: interface dotnetnuke dotnetnuke-5

升级到DNN 5.5.0后,我们必须在所有业务对象上实施IHydratable

这个想法似乎是一个很好的方式,但在玩IHydratable后,我不再那么肯定了。

有两种可能性:

  1. 我做错了
  2. IHydratable强制您使用select *构建所有查询
  3. 商业案例:

    • 我的第一个sproc会返回BgIdBgShortDesc
    • 我的第二个sproc返回BgIdBgReportedUser

    我的IHydratable如下所示:

    public class Bug : IHydratable
    { 
      public int BgId { get; set; }
      public string BgShortDesc { get; set; }
      public int BgReportedUser { get; set; }
      public DateTime BgReportedDate { get; set; }
    
      public Bug() { }
    
      public int KeyID
      {
        get { return BgId; }
        set { BgId = value; }
      }
    
      public void Fill(IDataReader dr)
      {
        BgId = Convert.ToInt32(Null.SetNull(dr["BgId"], BgId));
        BgShortDesc = Convert.ToString(Null.SetNull(dr["BgShortDesc"], BgShortDesc));
        BgReportedUser = Convert.ToInt32(Null.SetNull(dr["BgReportedUser"], BgReportedUser));
        BgReportedDate = Convert.ToDateTime(Null.SetNull(dr["BgReportedDate"], BgReportedDate));
      }
    }
    

    fill方法将在上述任何一个sprocs上抛出IndexOutOfRangeException,因为并非所有字段都返回IDataReader

    解决问题的简单方法是在所有的sprocs中使用select *,但这不是一个好习惯。

    在这种情况下实施IHydratable的正确方法是什么?

    P.S。 请注意,我的示例过于简单,以便明白这一点。

1 个答案:

答案 0 :(得分:1)

我在another forum

上得到了一个可行的答案

以下是建议:

    public void Fill(IDataReader dr)
    {
            if (dr.ColumnExists("BgId"))
            {
              BgId = Convert.ToInt32(Null.SetNull(dr["BgId"], BgId));
            }
            //do the above for all the properties
    }

修改

通过在SO(@JamesEggers@Chad Grant)上的这2个答案的帮助下在IDataReader上编写扩展方法,找到了更好的方法。

    /// <summary>
    /// Check if the column exists in the datareader before accessing its value
    /// </summary>
    /// <param name="reader">DataReader</param>
    /// <param name="columnName">Column name</param>
    /// <returns>True if column exists, false if not</returns>
    public static bool ColumnExists(this IDataReader reader, string columnName)
    {
        for (int i = 0; i < reader.FieldCount; i++)
        {
            if (reader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
            {
                return true;
            }
        }

        return false;
    }