.net c# NHibernate QueryOver标准

NHibernate Criteria to QueryOver
2021-03-07
  •  译文(汉语)
  •  原文(英语)

我仍在学习NHibernate,并且想知道是否有人可以帮助我将以下标准转换为QueryOver等效标准.

我认为我的基础知识不高,但是查询子集合并添加别名时我有点迷茫.发布的条件查询确实返回了预期的数据,但是我不确定我对条件格式的所有魔术字符串的适应程度如何.

return Session.CreateCriteria<Person>()
    .Add(Restrictions.Eq("FirstName", firstName))
    .Add(Restrictions.Eq("LastName", lastName))
    .CreateCriteria("PartyContactMechanisms")
    .CreateAlias("ContactMechanism", "c")
    .Add(Restrictions.Eq("c.ElectronicAddressString", emailAddress))
    .UniqueResult<Person>();

编辑: 我能够使用以下QueryOver返回所需的结果.我以为我会发布解决方案,以防其他人解决.也欢迎您提供任何有关改进此代码的建议.

Person personAlias = null;
        ElectronicAddress emailAlias = null;
        PartyContactMechanism partyContactMechAlias = null;

        return Session.QueryOver(() => personAlias)
            .Where(p => p.FirstName == firstName)
            .And(p => p.LastName == lastName)
            .JoinQueryOver(() => personAlias.PartyContactMechanisms, () => partyContactMechAlias)
            .JoinAlias(() => partyContactMechAlias.ContactMechanism, () => emailAlias)
            .Where(() => emailAlias.ElectronicAddressString == emailAddress)
            .SingleOrDefault<Person>();
解决过程1

它可能看起来像这样:

// these are aliases, which we can/will use later, 
// to have a fully-type access to all properties
Person person = null;
PartyContactMechanism partyContactMechanisms = null;
ContactMechanism contactMechanism = null;

// search params
var firstName = ..;
var lastName  = ..;
var emailAddress = ..;

var query = session.QueryOver<Person>(() => person)
    // the WHERE
    .Where(() => person.FirstName == firstName)
    // the And() is just more fluent eq of Where()
    .And(() => person.LastName == lastName)
    // this collection we will join as criteria
    .JoinQueryOver(() => person.PartyContactMechanism, () => partyContactMechanisms)
    // its property as alias
    .JoinAlias(() => partyContactMechanisms.ContactMechanism, () => contactMechanism )
    // final filter 
    .Where(() => contactMechanism.Code == emailAddress)
    // just one result
    .Take(1)
    ;


var uniqueResult = query
    .List<Person>()
    .SingleOrDefault();

有关更多信息,请在这里深入了解:

注意:还要检查子查询,因为查询"集合"时这些子查询要好得多.只需搜索它们...并将它们用作子选择WHERE parentId IN (SELECT parentId FROM ChildTable...

速聊1:
我一直坚持下去,并使其起作用,但是我仍然接受此解决方案,因为它证实了我的工作方向正确.感谢您出色的分步说明以及进一步研究的链接.非常感激.
速聊2:
很有帮助.如果享受NHibernate,它是一种了不起的强大工具;)

I am still learning NHibernate and am wondering if someone could help me translate the following criteria to its QueryOver equivalent.

I think I have the basics down, but I am a little lost when querying the child collection and adding the alias. The criteria query posted does return the expected data, but I'm not sure how comfortable I am with all the magic strings of the criteria format.

return Session.CreateCriteria<Person>()
    .Add(Restrictions.Eq("FirstName", firstName))
    .Add(Restrictions.Eq("LastName", lastName))
    .CreateCriteria("PartyContactMechanisms")
    .CreateAlias("ContactMechanism", "c")
    .Add(Restrictions.Eq("c.ElectronicAddressString", emailAddress))
    .UniqueResult<Person>();

Edit: I was able to return the desired result using the following QueryOver. I thought I'd post the solution in case it helps someone else out. Any suggestions on improving this code are welcome as well.

Person personAlias = null;
        ElectronicAddress emailAlias = null;
        PartyContactMechanism partyContactMechAlias = null;

        return Session.QueryOver(() => personAlias)
            .Where(p => p.FirstName == firstName)
            .And(p => p.LastName == lastName)
            .JoinQueryOver(() => personAlias.PartyContactMechanisms, () => partyContactMechAlias)
            .JoinAlias(() => partyContactMechAlias.ContactMechanism, () => emailAlias)
            .Where(() => emailAlias.ElectronicAddressString == emailAddress)
            .SingleOrDefault<Person>();
Solutions1

It could look like this:

// these are aliases, which we can/will use later, 
// to have a fully-type access to all properties
Person person = null;
PartyContactMechanism partyContactMechanisms = null;
ContactMechanism contactMechanism = null;

// search params
var firstName = ..;
var lastName  = ..;
var emailAddress = ..;

var query = session.QueryOver<Person>(() => person)
    // the WHERE
    .Where(() => person.FirstName == firstName)
    // the And() is just more fluent eq of Where()
    .And(() => person.LastName == lastName)
    // this collection we will join as criteria
    .JoinQueryOver(() => person.PartyContactMechanism, () => partyContactMechanisms)
    // its property as alias
    .JoinAlias(() => partyContactMechanisms.ContactMechanism, () => contactMechanism )
    // final filter 
    .Where(() => contactMechanism.Code == emailAddress)
    // just one result
    .Take(1)
    ;


var uniqueResult = query
    .List<Person>()
    .SingleOrDefault();

for more information, please take a deep look here:

NOTE: also check Subqueries, becuase these are much better when querying the "collections". Just search for them... and use them as subselect WHERE parentId IN (SELECT parentId FROM ChildTable...

Talk1:
I kept at it and got it to work, but I still accept this solution since it confirms that I was on the right track. Thank you for the excellent step by step explanation and the links for further research. Much appreciated.
Talk2:
Great if that helped ... Enjoy NHibernate, it is amazing and powerful tool ;)
转载于:https://stackoverflow.com/questions/23002870/nhibernate-criteria-to-queryover

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入