标签: nhibernate-criteria

如何使用NHibernate ICriteria API表达此LINQ查询?

我目前的项目是使用NHibernate 3.0b1和NHibernate.Linq.Query<T>()API.我对LINQ非常流利,但我对HQL或ICriteria API没有任何经验.IQueryable API不支持我的一个查询,因此我认为我需要使用以前的API之一 - 但我不知道从哪里开始.

我已经尝试在网上搜索ICriteria的一个很好的"入门"指南,但我发现的唯一例子要么太简单了,要么在这里申请,要么太高级我无法理解.如果有人有一些好的学习材料可以传递,我们将不胜感激.

在任何情况下,我要查询的对象模型看起来像这样(大大简化,省略了非相关属性):

class Ticket {
    IEnumerable<TicketAction> Actions { get; set; }
}
abstract class TicketAction {
    Person TakenBy { get; set; }
    DateTime Timestamp { get; set; }
}
class CreateAction : TicketAction {}
class Person {
    string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

A Ticket有一个TicketAction描述其历史的集合.TicketAction亚型包括CreateAction,ReassignAction,CloseAction等所有的门票已经一CreateAction创建时添加到此集合.

此LINQ查询正在搜索具有给定名称的人创建的票证.

var createdByName = "john".ToUpper();
var tickets = _session.Query<Ticket>()
    .Where(t => t.Actions
        .OfType<CreateAction>() …
Run Code Online (Sandbox Code Playgroud)

nhibernate linq-to-nhibernate nhibernate-criteria

5
推荐指数
1
解决办法
569
查看次数

如何使用NHibernate Criteria API进行多个连接

我有以下数据模型:

Page
- Id      // Pk
- Type    // int

Section
- Id      // Pk
- Page    // Fk

Comment
- Id      // Pk
- Section // Fk
- Date    // DateTime
Run Code Online (Sandbox Code Playgroud)

我试图在一个时间限制内查询与某个页面相关的所有注释(Say page.id = 2和page.Type = 1).我试过这样的:

   var criteria = session.CreateCriteria<Comment>()

   .Add(Restrictions.Eq("Section.Page.Id", pageId))
   .Add(Restrictions.Eq("Section.Page.Type", pageType))
   .Add(Restrictions.Ge("Date", start))
   .Add(Restrictions.Lt("Date", end));
Run Code Online (Sandbox Code Playgroud)

但是,这会失败,因为我收到一条错误,说"无法解析属性:Page:TestNamespace.Comment".这通常表示映射错误,但它适用于所有其他情况,所以我倾向于相信错误在于查询.

更糟糕的是,在某些情况下,Comment.Section可能为null(有些注释与section或page无关).在那种情况下,我想忽略这些评论.

有什么建议?

谢谢!

c# nhibernate nhibernate-mapping fluent-nhibernate nhibernate-criteria

5
推荐指数
1
解决办法
4879
查看次数

使用NHibernate Criteria的HAVING子句中的多个条件?

我正在尝试使用NHibernate的Criteria API来编写相当于这个:

select foo_id from foo_history
group by foo_id
having sum(bar_in) > 0 or sum(baz_in) > 0;
Run Code Online (Sandbox Code Playgroud)

使用此映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MVC"
                   namespace="MVC.Model.Things">
  <class name="MVC.Model.Things.FooHistory, MVC"
         table="foo_history">
    <id name="ID" column="foo_hist_id" type="guid"
        unsaved-value="00000000-0000-0000-0000-000000000000">
      <generator class="guid.comb" />
    </id>

    <!-- Properties -->
    <property name="BarIn" column="bar_in" type="decimal"
              precision="19" scale="4" not-null="true" />
    <property name="BazIn" column="baz_in" type="decimal"
              precision="19" scale="4" not-null="false" />

    <!-- Foreign Keys -->
    <many-to-one name="Foo" column="foo_id"
                 class="MVC.Model.Things.Foo, MVC.Model.Things"
                 not-null="true" />
  </class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)

和这个Criteria代码(分离,因为它将是一个子查询):

var results = DetachedCriteria.For<FooHistory>("fh")
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.GroupProperty(Projections.Id()))
        .Add(Projections.Sum("fh.BarIn"))
        .Add(Projections.Sum("fh.BazIn"))) …
Run Code Online (Sandbox Code Playgroud)

c# mysql nhibernate nhibernate-criteria having-clause

5
推荐指数
1
解决办法
1306
查看次数

如何为给定的sql查询创建条件查询

我正在为这个等效的SQL查询创建一个ICriteria查询.

SELECT fCustomerID,
       ISNULL(
                (SELECT SUM(payinv.fAmount) AS Expr1
                 FROM dbo.tARPayment AS pay
                 INNER JOIN dbo.tARPaymentInvoice AS payinv ON pay.fPaymentID = payinv.fPaymentID
                 INNER JOIN dbo.tARInvoice AS inv ON payinv.fInvoiceID = inv.fARInvoiceID
                 WHERE (pay.fIsPosted = CASE pay.fPaymentType WHEN 'CM' THEN 0 WHEN 'EPD' THEN 0 ELSE 1 END)
                   AND (inv.fCustomerID <> dbo.tARCustomer.fCustomerID)
                   AND (pay.fCustomerID = dbo.tARCustomer.fCustomerID)), 0)
FROM dbo.tARCustomer
GROUP BY fCustomerID
Run Code Online (Sandbox Code Playgroud)

但我无论如何都无法生成如何生成等效的nhibernate ICriteria查询.

这是付款类

public partial class tARPayment 
{
    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see …
Run Code Online (Sandbox Code Playgroud)

c# nhibernate hibernate fluent-nhibernate nhibernate-criteria

5
推荐指数
1
解决办法
686
查看次数

NHibernate:如何在投影中选择根实体

Ayende描述了一种非常好的获取页面计数的方法,以及一个查询中的特定数据页面:

http://ayende.com/blog/2334/paged-data-count-with-nhibernate-the-really-easy-way

他的方法看起来像:

IList list = session.CreateQuery("select b, rowcount() from Blog b")
              .SetFirstResult(5)
              .SetMaxResults(10)
              .List();
Run Code Online (Sandbox Code Playgroud)

唯一的问题是这个例子是在HQL中,我需要在ICriteria查询中做同样的事情.要达到与ICriteria相当的水平,我需要做类似的事情:

IList list = session.CreateCriteria<Blog>()
              .SetFirstResult(5)
              .SetMaxResults(10)
              .SetProjection(Projections.RootEntity(), Projections.SqlFunction("rowcount", NHibernateUtil.Int64))
              .List();
Run Code Online (Sandbox Code Playgroud)

问题是没有Projections.RootEntity()这样的东西.有没有办法选择根实体作为投影列表中的投影之一?

是的,我知道我可以使用CriteriaTransform.TransformToRowCount(),但这需要执行两次查询 - 一次用于结果,一次用于行计数.使用Futures可以通过将其减少到一次往返来帮助一点,但它仍然在SQL Server上执行两次查询.对于密集查询,这是不可接受的.我想避免开销,并在同一查询中返回行计数和结果.

基本问题是:使用ICriteria,有没有办法同时选择根实体和其他一些投影?

编辑:一些相关链接:

https://nhibernate.jira.com/browse/NH-1372?jql=text%20~%20%22entity%20projection%22

https://nhibernate.jira.com/browse/NH-928

nhibernate projection rowcount data-paging nhibernate-criteria

5
推荐指数
1
解决办法
1343
查看次数

Nhibernate QueryOver不会获得最新的数据库更改

我正在尝试从数据库更新记录QueryOver.我的代码最初创建一个实体并保存在数据库中,然后在外部数据库上更新相同的记录(从其他程序,手动或在其他机器上运行的相同程序),当我queryOver通过字段更改调用过滤时,查询得到记录,但没有最新的变化.

这是我的代码:

//create the entity and save in database
MyEntity myEntity = CreateDummyEntity();
myEntity.Name = "new_name";

MyService.SaveEntity(myEntity);

// now the entity is updated externally changing the name property with the 
// "modified_name" value (for example manually in TOAD, SQL Server,etc..)

//get the entity with QueryOver
var result = NhibernateHelper.Session
                 .QueryOver<MyEntity>()
                 .Where(param => param.Name == "modified_name")
                 .List<T>();
Run Code Online (Sandbox Code Playgroud)

前一个语句获取的集合只有一个记录(好),但是使用旧值而不是"modified_name" 建立了name属性.

我怎么能解决这个问题?一级缓存令我不安?出现同样的问题

CreateCriteria<T>();
Run Code Online (Sandbox Code Playgroud)

我的NhibernateHelper中的会话在任何时候都没有因应用程序框架要求而关闭,只是为session.Save()关联的每个提交创建了事务.如果我打开一个新会话来执行查询显然我从数据库中获得了最新的更改,但设计要求不允许这种方法.

此外,我已经在NHibernate SQL输出中检查了正在执行带有WHERE子句的select(因此Nhibernate命中数据库)但是不更新返回的对象!

UPDATE

这是调用session.Save之后SaveEntity中的代码:完成对Commit方法的调用

public virtual void Commit() 
{ …
Run Code Online (Sandbox Code Playgroud)

nhibernate nhibernate-criteria queryover

5
推荐指数
1
解决办法
5448
查看次数

在其他查询的结果上执行nHibernate icriteria(两个不同的查询)

有没有办法将ICriteria结果用作后续条件查询的"基础"?

例如,如果我想创建一个查询

SELECT department_id, sum(cost) AS total
FROM payment
GROUP BY payment.department_id
Run Code Online (Sandbox Code Playgroud)

将结果存储为query0,然后执行查询

SELECT department.name, total
FROM department, query0
JOIN LEFT ON department.id=query0.id
WHERE total > 3
Run Code Online (Sandbox Code Playgroud)

我不希望一次执行一个单独的大查询(这是使用子查询创建ICriteria的结果).请注意,我对第一个查询的结果有一个选择/限制,同时在第二个查询的投影中包含其中一个列.

使用字符串动态生成标准以标识类.

nhibernate criteria nhibernate-criteria

5
推荐指数
1
解决办法
265
查看次数

Nhibernate查询具有包含值的Dictionary属性的项目

我需要一种方法来在Nhibernate中查询具有包含值的Dictionary属性的项目.

假设:

public class Item
{
     public virtual IDictionary<int, string> DictionaryProperty {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

和映射:

    public ItemMap()
    {
        HasMany(x => x.DictionaryProperty)
            .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
            .AsMap<string>(
                index => index.Column("IDNumber").Type<int>(),
                element => element.Column("TextField").Type<string>().Length(666)
                )
            .Cascade.AllDeleteOrphan()
            .Fetch.Join();
    }
Run Code Online (Sandbox Code Playgroud)

我想查询所有Item具有字典值"SomeText"的s.Linq中的以下示例失败:

session.Query<Item>().Where(r => r.DictionaryProperty.Any(g => g.Value == "SomeText"))
Run Code Online (Sandbox Code Playgroud)

有错误

cannot dereference scalar collection element: Value
Run Code Online (Sandbox Code Playgroud)

那么在NHibernate中有没有办法实现这一点?Linq不是独家要求,而是优先考虑.并不是说我对查询可以使用的字典不感兴趣.ContainsKey.Φορ 是相似但不相同的

nhibernate fluent-nhibernate linq-to-nhibernate nhibernate-criteria

5
推荐指数
1
解决办法
1109
查看次数

在NHibernate中设置TimeOut Expired

我在sql server 2008 R2中有一个存储过程,它工作正常,但突然它抛出了TimeOut Expiration的异常.

BmDaoSession.CreateSQLQuery("exec SP_Name @Param1  = '" + clientCode + "', @Param2 ='" + existingDatabase + "', @Flag='" + flag + "'").ExecuteUpdate();
Run Code Online (Sandbox Code Playgroud)

我使用上面的NHibernate命令来调用我的SP.

我的问题是如何在NHibernate中设置TimeOut Expiration.谢谢

c# sql sql-server nhibernate nhibernate-criteria

5
推荐指数
1
解决办法
4568
查看次数

如何使用NHibernate查询外键列,而不检索相关实体

说我有两个班级:ParentChild.A Parent有一个属性Children,当然是一组Child对象.

Child没有ParentId财产.它确实有一个Parent属性.

所以,我的NHibernate映射Child包括:

<many-to-one name="Parent" class="Parent" column="ParentId" cascade="save-update" />
Run Code Online (Sandbox Code Playgroud)

我的Parent映射包括:

<bag name="children" access="field" inverse="true" cascade="all-delete-orphan">
    <key column="ParentId" />
    <one-to-many class="Child" />
</bag>
Run Code Online (Sandbox Code Playgroud)

现在这就是我想要做的事情:我希望得到Child一定的所有对象ParentId.我知道我可以先得到Parent它然后归还它的Children财产.但是,如果我想Child直接查询表怎么办?

如果它是一个映射属性(例如Name),我可以使用NHibernate的标准,但在这种情况下,ParentId没有映射.

我尝试过使用类似的东西:

criteria.Add(Restrictions.Eq("Parent.Id", 1));
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我使用了SQLCriterion(如这里所解释的),但是一位朋友/同事让我觉得必须有更好的方法.

有任何想法吗?什么与投影和Restrictions.EqProperty

nhibernate nhibernate-criteria

4
推荐指数
2
解决办法
4520
查看次数