0

学校があり、学校には生徒のコレクションがある単純なテスト オブジェクト モデルがあります。

特定の年齢以上の学校とそのすべての生徒を取得したいと考えています。

次のクエリを実行して、特定の学校と特定の年齢以上の子供を取得します。

    public School GetSchoolAndStudentsWithDOBAbove(int schoolid, DateTime dob)
    {
      var school = this.Session.CreateCriteria(typeof(School))
        .CreateAlias("Students", "students")
        .Add(Expression.And(Expression.Eq("SchoolId", schoolid), Expression.Gt("students.DOB", dob)))
        .UniqueResult<School>();

      return school;
    }

これはすべて正常に機能し、クエリがデータベースに送信され、予想される行数が返されることがわかります。

ただし、次のいずれかを実行すると、別のクエリを実行することで、(前の要求に関係なく) 特定の学校の生徒の総数が得られます。

        foreach (Student st in s.Students)
        {
            Console.WriteLine(st.FirstName);
        }

        Assert.AreEqual(s.Students.Count, 3);  

誰でも理由を説明できますか?

4

3 に答える 3

2

Schoolクラスでクエリを実行し、マップされた関連オブジェクトではなく、Schoolクラスで結果を制限しました。

今、これを行うには多くの方法があります。IanLが言ったように静的フィルターを作成できますが、実際には柔軟性がありません。mxmissileのようにコレクションを繰り返すことができますが、それは醜くて遅いです(特に遅延読み込みの考慮事項を考慮すると)

2つの異なるソリューションを提供します。最初に、使用しているクエリを維持し、コレクションに対して動的フィルターを実行し(遅延ロードされたコレクションを維持します)、データベースへのラウンドトリップを実行します。

var school = GetSchoolAndStudentsWithDOBAbove(5, dob);
IQuery qDob = nhSession.CreateFilter(school.Students, "where DOB > :dob").SetDateTime("dob", dob);
IList<Student> dobedSchoolStudents = qDob.List<Student>();

2番目のソリューションでは、学校と生徒の両方を1回のショットで取得します。

object result = nhSession.CreateQuery(
    "select ss, st from School ss, Student st 
    where ss.Id = st.School.Id and ss.Id = :schId and st.DOB > :dob")
    .SetInt32("schId", 5).SetDateTime("dob", dob).List();

ssはSchoolオブジェクトであり、stはStudentコレクションです。

そして、これは間違いなく、現在使用している基準クエリを使用して実行できます(プロジェクションを使用)

于 2010-03-11T09:24:44.133 に答える
1

残念ながらs.Students、「クエリされた」結果は含まれません。生徒が目標を達成するには、別のクエリを作成する必要があります。

foreach(var st in s.Students.Where(x => x.DOB > dob))
     Console.WriteLine(st.FirstName);

警告:マッピングによっては、データベースへの2回目の移動が行われ、すべての生徒が取得されます。

よくわかりませんが、プロジェクションを使用して1つのクエリでこれらすべてを実行できる可能性がありますが、私はその専門家ではありません。

于 2010-03-10T15:19:55.777 に答える
0

データをフィルタリングするオプションがあります。クエリ mxmissle オプションのインスタンスが 1 つしかない場合は、より適切な選択になります。

Nibernate フィルターのドキュメント

フィルターには用途がありますが、使用しているバージョンによっては、フィルター処理されたコレクションが正しくキャッシュされないという問題が発生する可能性があります。

于 2010-03-10T15:29:07.073 に答える