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

当用户通过名称在系统中搜索客户端时,它需要搜索所有主客户端以及一跳之外的辅助客户端。(即如果设置了 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 可能为空。

4

2 回答 2

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 回答
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 回答