对于NHibernate,我仍然是一个n00b。假设我有以下内容:
var myCriteria = this.Session.CreateCriteria(typeof(SomeModel))
.Add(Restrictions.Eq("SomeProperty", someValue);
然后,假设我想以可重用的方式添加标准。意思是,我想制定一个自定义标准。我在网上看到非常非常少的信息。具体来说,我想转向以下内容:
var myCriteria = this.Session.CreateCriteria(typeof(SomeModel))
.Add(Restrictions.Eq("SomeProperty", someValue)
.CreateAlias("SomeClass", "alias", JoinType.LeftOuterJoin)
.Add(Restrictions.Eq("alias.SomeOtherProperty", someOtherValue));
进入以下内容:
var myCriteria = this.Session.CreateCriteria(typeof(SomeModel))
.Add(Restrictions.Eq("SomeProperty", someValue)
.Add(this.GetAliasCriterion());
从而提取
.CreateAlias("SomeClass", "alias", JoinType.LeftOuterJoin)
.Add(Restrictions.Eq("alias.SomeOtherProperty", someOtherValue));
进入方法。
这可能吗?这是如何工作的?
答案 0 :(得分:1)
这是我经常使用的模式:
假设我有一个过滤器,可以在条件上添加特定的Restrictions
。
(你甚至可以把它变成一个扩展类)
public class DeletedFlagFilter{
public DetachedCriteria AddFilter(DetachedCriteria criteria)
{
criteria.AddRestrictions("Deleted", true);
return criteria;
}
}
上述课程的来电者说(FindDeletedUserClass
)然后会使用上面的助手类来添加定义已删除用户所需的所有限制,如下所示:
public class FindDeletedUserClass{
public DetachedCriteria BuildCriteria(){
var deletedUserCriteria = DetachedCriteria.For<User>();
var helper = new DeletedFlagFilter();
helper.AddFilter(deletedUserCriteria);
return deletedUserCriteria;
}
}
实际访问NHibernate会话的分离服务层然后可以将DetachedCriteria转换为连接到会话的条件并执行相同的操作。
var myDetachedCriteria = DetachedCriteria.For<SomeModel>();
var sessionCriteria = myDetachedCriteria.GetExecutableCriteria(Session);
使用上面的模式,您可以在DeletedFlagFilter
类中封装已删除的功能。将来,如果已删除的定义发生更改,则DeletedFlagFilter
类
修改:有一个很好的教程,你可以阅读here
答案 1 :(得分:1)
你可以用扩展方法做到这一点。我会小心的,通常你会想看到查询正在进行的所有别名(连接)。
public static class CriteriaExtensions
{
public static ICriteria AddSomeClassAliasRestriction(this ICriteria c, object value)
{
return c.CreateAlias("SomeClass", "alias", JoinType.LeftOuterJoin)
.Add(Restrictions.Eq("alias.SomeOtherProperty", value));
}
}
并像......一样使用它。
var myCriteria = this.Session.CreateCriteria(typeof(SomeModel))
.Add(Restrictions.Eq("SomeProperty", someValue)
.AddSomeClassAliasRestriction(someOtherValue);
答案 2 :(得分:1)
就个人而言,我更喜欢使用Linq来NHibernate而不是标准。它已经包含在最新版本的NHibernate中,只需将“using NHibernate.Linq
”添加到您的cs文件中,因为所有L2H方法都是扩展方法。
如果我想使用L2H重复使用谓词/标准,它将看起来像这样:
public partial class Person
{
//yes, this is kind of ugly, but if I have a complicated predicate that
//I want to reuse, I'll make a static method on the entity itself.
public static Expression<Func<Person, bool>> HasPrimaryRole(string roleCode)
{
return p => p.Roles.Any(r => r.RoleCode == roleCode && r.IsPrimary);
}
}
用法如下:
var session = GetSession();
var midwestSalesManagers = session.Query<Person>()
.Where(p => p.Region == "Midwest").Where(Person.HasPrimaryRole("RSM"));
或者您可以这样做:
var midwestSalesManagers = session.Query<Person>()
.Where(Expression.And(p => p.Region == "Midwest", Person.HasPrimaryRole("RSM")));
我还没有完全测试过所有这些,但我希望你能得到我的漂移。我认为它非常易读并且避免使用魔术字符串,所以它对重构很友好。