2009-09-29 60 views
0

我正在創建一個使用ActiveRecord作爲數據層的C#應用​​程序。我創建了一個名爲UserGrabber的業務類,它應該通過使用它的屬性將過濾器發送到ActiveRecord.Find方法來查找用戶。ActiveRecord在查找方法中創建動態條件

例如一個用戶類。客戶需要找到有活動目錄名稱以「安娜」,用含4229. SSN所有用戶,那麼我願做

UserGrabber grabber = new UserGrabber(); 
grabber.ADName = "anna"; 
grabber.SSN = "4229"; 
grabber.Grab(); 

foreach(User user in grabber.Users) 
{ 
    Console.WriteLine(user.FullName); 
} 

訣竅是,我沒有將信息發送到UserGrabber除非我想按照它過濾,否則我可以只發送grabber.ADName,然後SSN不會被過濾。

問題是我似乎無法理解如何在ActiveRecord中執行此操作。也許我可以使用ExecuteQuery(Castle.ActiveRecord.IActiveRecordQuery)或FindAll(NHibernate.Criterion.ICriterion)?

回答

0

好吧,我已經想通了這一點:)

我開始用下面的實現

public class ActiveRecordCustomBase<T> : ActiveRecordBase<T> 
    { 
     public static string GetPropertyColumnName(string propertyName) 
     { 
      System.Reflection.PropertyInfo property = typeof(T).GetProperty(propertyName); 
      object[] attributes = property.GetCustomAttributes(false); 

      if (attributes != null) 
      { 
       foreach (object attr in attributes) 
       { 
        if (attr is PrimaryKeyAttribute) 
        { 
         return ((PrimaryKeyAttribute)attr).Column; 
        } 
        else if (attr is PropertyAttribute) 
        { 
         return ((PropertyAttribute)attr).Column; 
        } 
       } 
      } 
      return null; 
     } 
    } 

通過讓我所有的ActiveRecord類從ActiveRecordCustomBase繼承創建一個名爲ActiveRecordCustomBase類,它允許我使用函數GetPropertyColumnName,以便列映射將位於1個位置(因此不需要選擇DRY principal)。

接下來,我創建了我的業務類中的查找方法,看起來像這樣:

UserCriteria userCriteria = (UserCriteria)criteria; 
       if (userCriteria.UserId != 0) 
       { 
        UserDAO userDAO = UserDAO.TryFind(userCriteria.UserId); 
       } 
       else if (userCriteria.MasterDataId != 0) 
       { 
        UserDAO userDAO = UserDAO.FindOne(Restrictions.Eq(UserDAO.GetPropertyColumnName("ExternalId1"), userCriteria.MasterDataId)); 

       } 
       else if (!userCriteria.ADName.Equals(string.Empty)) 
       { 
        UserDAO userDAO = UserDAO.FindOne(Restrictions.Eq(UserDAO.GetPropertyColumnName("ADName"), userCriteria.ADName.ToLower())); 
       } 

這是足以讓動態行爲我正在尋求