2009-09-29 4 views
0

Je crée une application C# en utilisant ActiveRecord comme datalayer. J'ai créé une classe d'affaires nommée UserGrabber qui est supposée trouver des utilisateurs en utilisant ses propriétés à envoyer en tant que filtres dans une méthode ActiveRecord.Find.ActiveRecord crée des conditions dynamiques dans la méthode find

Par exemple, une classe User. Le client a besoin de trouver tous les utilisateurs qui ont le nom de répertoire actif commençant par « anna » et contenant 4229. Puis SSN je voudrais faire

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

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

L'astuce est que je ne dois pas envoyer des informations à UserGrabber à moins que je veuille filtrer par lui, j'aurais pu envoyer juste dans grabber.ADName, alors le SSN ne serait pas filtré par.

Le problème est que je n'arrive pas à comprendre comment faire cela dans ActiveRecord. Peut-être que je pourrais utiliser l'ExecuteQuery (Castle.ActiveRecord.IActiveRecordQuery) ou FindAll (NHibernate.Criterion.ICriterion)?

Répondre

0

D'accord, j'ai compris cela :)

J'ai commencé par la création de classe nommée ActiveRecordCustomBase avec la mise en œuvre suivante

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; 
     } 
    } 

En laissant toutes mes classes ActiveRecord héritent de ActiveRecordCustomBase, il me permet d'utiliser la fonction GetPropertyColumnName afin que le mappage de colonne se trouve à 1 emplacement (par conséquent ne pas vialoting le DRY principal).

Ensuite, je créé une méthode de recherche dans ma classe d'affaires qui ressemble à ceci:

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())); 
       } 

Ce fut suffisant pour que le comportement dynamique que je cherchais

Questions connexes