1

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

メソッドに。

これは可能ですか?これはどのように作動しますか?

4

3 に答える 3

1

これは私が通常使用するパターンです:

Restrictions基準に特定のものを追加するフィルターがあるとしましょう。(拡張クラスにすることもできます)

public class DeletedFlagFilter{

  public DetachedCriteria AddFilter(DetachedCriteria criteria)
  {
        criteria.AddRestrictions("Deleted", true);
        return criteria;
  }
}

次に、上記のクラスsay(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の定義が変更された場合、クラスで唯一の変更が発生します

編集:ここで読むことができる素晴らしいチュートリアルがあります

于 2012-06-22T21:14:44.740 に答える
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);
于 2012-06-22T21:14:53.863 に答える
1

個人的には、基準ではなくNHibernateよりもLinqを使用する方が好きです。これはすでにNHibernateの最新リリースに含まれていusing NHibernate.Linqます。すべてのL2Hメソッドは拡張メソッドであるため、csファイルに「」を追加するだけです。

述語/基準を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")));

私はこれらすべてを完全にテストしていませんが、あなたが私のドリフトを手に入れてくれることを願っています。かなり読みやすく、マジックストリングの使用を避けているので、リファクタリングに適していると思います。

于 2012-06-22T21:29:22.297 に答える