首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate - CreateCriteria vs CreateAlias

NHibernate - CreateCriteria vs CreateAlias
EN

Stack Overflow用户
提问于 2009-05-22 17:44:24
回答 3查看 32.9K关注 0票数 27

假设以下场景:

代码语言:javascript
复制
class Project{
   public Job Job;
}

class Job{
   public Name;
}

假设我想使用Criteria API来搜索Job名称为"sumthing“的所有项目。

我可以使用CreateAlias为工作创建一个别名,并使用它访问名称,或者我可以为属性工作创建一个新的条件,并按名称进行搜索。

性能方面,有什么不同吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-28 14:11:46

考虑到这些需求没有区别,生成的SQL是相同的:对于映射:

代码语言:javascript
复制
    <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="Project" table="Project">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="Id" sql-type="int" not-null="true" unique="true"/>
            <generator class="native" />
        </id>
        <many-to-one name="Job" column="FK_JobId" cascade="save-update" not-null="true" />
    </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="Job" table="Job">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="Id" sql-type="int" not-null="true" unique="true"/>
            <generator class="native" />
        </id>
        <property name="Name" type="String">
            <column name="Name" sql-type="nvarchar" length="50" not-null="true"/>
        </property>
    </class>
</hibernate-mapping>

和类

代码语言:javascript
复制
public class Project
    {
        public Project() { }

        public virtual int Id { get; set; }

        public virtual Job Job { get; set; }
    }
public class Job
    {
        public Job() { }

        public virtual int Id { get; set; }

        public virtual String Name { get; set; }
    }

这些标准定义

代码语言:javascript
复制
ICriteria criteriacrit = session
  .CreateCriteria(typeof (Project))
  .CreateCriteria("Job", "job")
  .Add(Restrictions.Eq("job.Name", "sometextA"));

ICriteria aliascrit = session
  .CreateCriteria(typeof (Project))
  .CreateAlias("Job", "job")
  .Add(Restrictions.Eq("job.Name", "sometextB"));

生成相同的SQL

代码语言:javascript
复制
SELECT 
  this_.Id as Id2_1_, 
  this_.FK_JobId as FK2_2_1_, 
  job1_.Id as Id1_0_, 
  job1_.Name as Name1_0_ 
FROM 
  Project this_ 
  inner join Job job1_ 
    on this_.FK_JobId=job1_.Id 
WHERE job1_.Name = @p0; @p0 = 'sometextA'

SELECT 
  this_.Id as Id2_1_, 
  this_.FK_JobId as FK2_2_1_, 
  job1_.Id as Id1_0_, 
  job1_.Name as Name1_0_ 
FROM
  Project this_ 
  inner join Job job1_ 
    on this_.FK_JobId=job1_.Id 
WHERE job1_.Name = @p0; @p0 = 'sometextB'

但是请注意,CreateAlias依赖于映射来生成关联,而CreateCriteria调用允许指定JoinType

所以,这些电话

代码语言:javascript
复制
ICriteria criteriacrit = session
  .CreateCriteria(typeof(Project))
  .CreateCriteria("Job",JoinType.LeftOuterJoin)
  .Add(Restrictions.Eq("Name", "sometextA"));

ICriteria aliascrit = session
  .CreateCriteria(typeof (Project))
  .CreateAlias("Job", "job")
  .Add(Restrictions.Eq("job.Name", "sometextB"));

生成这些SQL语句

代码语言:javascript
复制
SELECT 
  this_.Id as Id2_1_, 
  this_.FK_JobId as FK2_2_1_, 
  job1_.Id as Id1_0_, 
  job1_.Name as Name1_0_ 
FROM 
  Project this_ 
  **left outer** join Job job1_
    on this_.FK_JobId=job1_.Id 
WHERE job1_.Name = @p0; @p0 = 'sometextA'

SELECT 
  this_.Id as Id2_1_, 
  this_.FK_JobId as FK2_2_1_, 
  job1_.Id as Id1_0_, 
  job1_.Name as Name1_0_ 
FROM Project this_ 
  **inner join** Job job1_ 
    on this_.FK_JobId=job1_.Id 
WHERE job1_.Name = @p0; @p0 = 'sometextB'
票数 38
EN

Stack Overflow用户

发布于 2011-02-12 10:23:24

为了解释NHibernate 2.0 +中CreateCriteria和CreateAlias之间的区别,让我们看看下面的域模型。

代码语言:javascript
复制
public class Product
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual decimal Price { get; set; }
    public virtual Category Category { get; set; }
    public virtual IList<ProductStock> ProductStocks { get; set; }
}

public class Category
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual IList<Product> Products { get; set; }
}

public class ProductStock
{
    public virtual int Id { get; private set; }
    public virtual Product Product { get; set; }
    public virtual string WarehouseName { get; set; }
    public virtual int Stock { get; set; }
}   

现在,如果您编写以下条件来内部连接这些实体

代码语言:javascript
复制
var criteria = DetachedCriteria.For<Product>()
                .CreateCriteria("Category", JoinType.InnerJoin)
                .CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
                .Add(Restrictions.Le("ps.Stock",10));

上面的条件不起作用,因为当第一个CreateCriteria运行时,它返回"Category“实体,因此当第二个CreateCriteria执行时,它不会在"Category”实体中找到属性ProductStocks,查询将失败。

因此,编写此标准的正确方法是

代码语言:javascript
复制
var criteria = DetachedCriteria.For<Product>()
                .CreateAlias("Category", "c", JoinType.InnerJoin)
                .CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
                .Add(Restrictions.Le("ps.Stock",10));

当第一个CreateAlias运行时,它返回“产品”实体,当第二个CreateCriteria执行时,它将在“产品”实体中找到属性ProductStocks。

因此,TSQL将是这样的。

代码语言:javascript
复制
SELECT this_.ProductID     as ProductID8_2_,
       this_.Name          as Name8_2_,
       this_.Price         as Price8_2_,
       this_.CategoryID    as CategoryID8_2_,
       ps2_.ProductStockID as ProductS1_9_0_,
       ps2_.Stock          as Stock9_0_,
       ps2_.ProductID      as ProductID9_0_,
       ps2_.WarehouseID    as Warehous4_9_0_,
       c1_.CategoryID      as CategoryID0_1_,
       c1_.Name            as Name0_1_
FROM   [Product] this_
       inner join [ProductStock] ps2_ on this_.ProductID = ps2_.ProductID
       inner join [Category] c1_ on this_.CategoryID = c1_.CategoryID
WHERE  ps2_.Stock <= 10 

我希望这能有所帮助。

票数 23
EN

Stack Overflow用户

发布于 2010-09-02 19:14:12

createAlias()原样返回原始条件结果createCriteria()返回使用createCriteria构造的新条件

不同之处在于链接方法时,例如

cr.createAlias().add(Restrictions.ilike("code","abc"))将对实体cr.createCriteria(" parent ",“p”)添加限制,.add(Restrictions.ilike(“Restrictions.ilike”,"abc"))将对其父实体添加限制

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/899079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档