我正在使用ActiveRecord创建一个C#应用程序作为我的数据层。我创建了一个名为UserGrabber的业务类,它应该通过使用它的属性来发现用户作为过滤器发送到ActiveRecord.Find方法。
例如User类。客户端需要找到所有用户名为“anna”并且SSN包含4229的用户。然后我想做
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 :(得分:0)
好吧,我已经想到了这一点:)
我首先使用以下实现创建名为ActiveRecordCustomBase的类
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,它允许我使用函数GetPropertyColumnName,以便列映射将位于1位置(因此不会对DRY principal进行调制)。
接下来,我在我的业务类中创建了一个finder方法,如下所示:
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()));
}
这足以让我想要的动态行为