0

解決方法がわからないという奇妙な要件があります。

次のクラス定義を想定しています。

public class Client
{
    public Guid Id { get; set; }
    public String Person { get; set; }
    public IList<Client> SecondaryClients { get; set; }
    public Client PrimaryClient { get; set; }
} 

public class Person
{
    public Guid Id { get; set; }
    public String Name { get; set; }
}

ユーザーがシステムでクライアントを名前で検索する場合、1ホップ離れたセカンダリクライアントだけでなく、すべてのプライマリクライアントを検索する必要があります。(つまり、PrimaryClientが設定されている場合は、PrimaryClient.Person.Nameプロパティを確認する必要がありますが、PrimaryClient.PrimaryClientについて心配する必要はありません。)

DetachedCriteriaを使用すると、次のようになります。

var clientQuery = DetachedCriteria.For<Client>();
            clientQuery.Add(Restrictions.Disjunction()
                                .Add(Restrictions.Like("Person.Surname", lastName, MatchMode.Start))
                                .Add(Restrictions.Like("PrimaryClient.Person.Surname", lastName, MatchMode.Start))
                                .Add(Restrictions.Like("SecondaryClients.Person.Surname", lastName, MatchMode.Start)));
            var session = OpenSession();
            session.BeginTransaction();
            var clients = clientQuery.GetExecutableCriteria(session).Future<Client>();
            session.Transaction.Commit();
            session.Close();

明らかに、これはかなり遠いです。少し掘り下げてみると、エイリアスを設定する必要があることがわかりました。最初のものはPerson.Surnameを見つけるのが簡単でした:

var clientQuery = DetachedCriteria.For<Client>();
        clientQuery = clientQuery.CreateAlias("Person", "p");
        clientQuery.Add(Restrictions.Disjunction()
                            .Add(Restrictions.Like("p.Surname", lastName, MatchMode.Start))
                            .Add(Restrictions.Like("PrimaryClient.Person.Surname", lastName, MatchMode.Start))
                            .Add(Restrictions.Like("SecondaryClients.Person.Surname", lastName, MatchMode.Start)));
        var session = OpenSession();
        session.BeginTransaction();
        var clients = clientQuery.GetExecutableCriteria(session).Future<Client>();
        session.Transaction.Commit();
        session.Close();

ただし、私の人生では、PrimaryClient.Personのエイリアスに対して何ができるかわかりません。私はここで間違った道を進んでいますか?どんな助けでもいただければ幸いです。

注:最初に言及するのを忘れました。SecondaryClientsとPrimaryClientがnullである可能性があります。

4

2 に答える 2

0

スコアを維持している人たちのために、私はこれを行う方法を理解することができました。より効率的な方法があるかどうかはわかりませんが、DetachedCriteriaを使用してクエリを設定する方法は次のとおりです。

var clientQuery = DetachedCriteria.For<Client>("Client");
clientQuery = clientQuery.CreateAlias("Person", "p");

var primaryQuery = DetachedCriteria.For<Client>("Primary");
primaryQuery.SetProjection(Projections.Property("Primary.Id"));
primaryQuery.Add(Restrictions.EqProperty("Client.PrimaryClient", "Primary.Id"));
primaryQuery.CreateAlias("Person", "p");
primaryQuery.Add(Restrictions.Like("p.Surname", lastName, MatchMode.Start));

var secondaryQuery = DetachedCriteria.For<Client>();
secondaryQuery.SetProjection(Projections.Property("Id"));
secondaryQuery.CreateCriteria("SecondaryClients")
              .CreateCriteria("Person")
              .Add(Restrictions.Like("Surname", lastName, MatchMode.Start));

clientQuery.Add(Restrictions.Disjunction()
                    .Add(Restrictions.Like("p.Surname", lastName, MatchMode.Start))
                    .Add(Subqueries.Exists(primaryQuery))
                    .Add(Subqueries.PropertyIn("Id", secondaryQuery)));
于 2011-11-02T12:57:08.457 に答える
0

私はあなたがこのクエリを使うことができると思います:

var result = _session.Linq<Client>.Where(client => client.Person.Name.StartsWith(lastName) ||
                                                   client.PrimaryClient.Name.StartsWith(lastName) ||
                                                   client.SecondaryClients.Any(sClient =>  sClient.Person.Name.StartsWith(lastName)));
于 2011-11-02T16:59:06.250 に答える