C# 跨多个实体查询

C# 跨多个实体查询,c#,nhibernate,nhibernate-criteria,C#,Nhibernate,Nhibernate Criteria,我有一个奇怪的要求,我不知道如何解决 假设类定义如下: 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 Per

我有一个奇怪的要求,我不知道如何解决

假设类定义如下:

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; }
}
公共类客户端
{
公共Guid Id{get;set;}
公共字符串Person{get;set;}
公共IList次要客户端{get;set;}
公共客户端主客户端{get;set;}
} 
公共阶层人士
{
公共Guid Id{get;set;}
公共字符串名称{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();
var clientQuery=DetachedCriteria.For();
clientQuery.Add(Restrictions.Disjunction()
.Add(限制条件,如(“Person.lastName”、lastName、MatchMode.Start))
.Add(限制。例如(“PrimaryClient.Person.name”、lastName、MatchMode.Start))
.Add(限制,如(“SecondaryClients.Person.Nastname”、lastName、MatchMode.Start));
var session=OpenSession();
session.BeginTransaction();
var clients=clientQuery.GetExecutableCriteria(session.Future();
Commit();
session.Close();
现在很明显,这是远远不够的。在四处挖掘时,我发现我需要设置别名。第一种方法很容易找到此人。姓氏:

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();
var clientQuery=DetachedCriteria.For();
clientQuery=clientQuery.CreateAlias(“Person”,“p”);
clientQuery.Add(Restrictions.Disjunction()
.Add(限制条件,如(“p.lastName”、lastName、MatchMode.Start))
.Add(限制。例如(“PrimaryClient.Person.name”、lastName、MatchMode.Start))
.Add(限制,如(“SecondaryClients.Person.Nastname”、lastName、MatchMode.Start));
var session=OpenSession();
session.BeginTransaction();
var clients=clientQuery.GetExecutableCriteria(session.Future();
Commit();
session.Close();
然而,就我个人而言,我不确定我能为PrimaryClient.Person的别名做些什么。我走错路了吗?任何帮助都将不胜感激


注:我原来忘了提。有可能SecondaryClient和PrimaryClient都是空的。

对于那些保持分数的客户,我能够想出如何做到这一点。我不确定是否有更有效的方法,但是下面是我如何使用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)));
var clientQuery=DetachedCriteria.For(“客户”);
clientQuery=clientQuery.CreateAlias(“Person”,“p”);
var primaryQuery=DetachedCriteria.For(“主”);
SetProjection(Projections.Property(“Primary.Id”);
添加(Restrictions.EqProperty(“Client.PrimaryClient”、“Primary.Id”);
CreateAlias(“Person”,“p”);
Add(Restrictions.Like(“p.names”、lastName、MatchMode.Start));
var secondaryQuery=DetachedCriteria.For();
secondaryQuery.SetProjection(Projections.Property(“Id”));
secondaryQuery.CreateCriteria(“SecondaryClients”)
.CreateCriteria(“人”)
.Add(限制,如(“姓氏”、姓氏、匹配模式.Start));
clientQuery.Add(Restrictions.Disjunction()
.Add(限制条件,如(“p.lastName”、lastName、MatchMode.Start))
.Add(subquerys.Exists(primaryQuery))
.Add(subquerys.PropertyIn(“Id”,secondaryQuery));

我认为您可以使用以下查询:

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)));
var result=\u session.Linq.Where(client=>client.Person.Name.StartsWith(lastName)||
client.PrimaryClient.Name.StartsWith(lastName)||
client.SecondaryClients.Any(sClient=>sClient.Person.Name.StartsWith(lastName));

我认为您的类设计并不完美,我指的是具有主客户端和一些辅助客户端的客户端类。我觉得有点奇怪,我完全同意。可悲的是,我在开发周期的后期参与了这个项目,对如何设计东西没有发言权。