Запросы к нескольким объектам - PullRequest
0 голосов
/ 02 ноября 2011

У меня странное требование, я не знаю, как его решить.

Предполагая следующее определение класса:

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

Когда пользователь ищет в системе клиента по имени,он должен искать все первичные клиенты, а также вторичные клиенты, которые находятся на расстоянии одного шага.(т.е. если 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.Sameame:

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 равны нулю.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2011

Я думаю, что вы можете использовать этот запрос:

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)));
0 голосов
/ 02 ноября 2011

Для тех, кто ведет счет, я смог понять, как это сделать. Я не уверен, есть ли более эффективный способ, однако вот как я настраиваю запрос, используя 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)));
...