简体   繁体   English

NHibernate:如何使用CreateSQLQuery返回标量值列表(从一列)?

[英]NHibernate: How to return list of scalar values (from one column) using CreateSQLQuery?

What is the best/cleanest method of calling a native SQL returning a list of scalar values (ints in my case) having ISession object? 调用本机SQL返回具有ISession对象的标量值(本例中为int)列表的最佳/最干净方法是什么?

I am trying to run the following but I am always getting some errors: 我正在尝试运行以下命令,但始终会遇到一些错误:

var query = _session.CreateSQLQuery("SELECT Id FROM SomeTable");

A. var ids = query.List<int>(); // <-- throws ArgumentNullException "Value cannot be null.\r\nParameter name: item"
B. var ids = query.List(); returns one element array with no valid information.
C. query.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean<int>());
var ids = query.List<int>(); // throws PropertyNotFoundException: "Could not find a setter for property 'Id' in class 'System.Int32'"

Is there a way to retrieve a list of ints without creating an entity class containing just one int property named Id? 有没有一种方法可以检索整数列表,而无需创建仅包含一个名为Id的整数属性的实体类?

When you call List from CreateSQLQuery you will get a instance of IList and it internally it is a List<object> . 当您从CreateSQLQuery调用List ,将获得IList一个实例,它在内部是List<object> If you have null values on this result, you will not be able to convert to int because it is a value type. 如果此结果具有空值,则将无法转换为int因为它是值类型。 So, a solution is to iterate over the result and convert it when it is a valid integer. 因此,一种解决方案是迭代结果,并在结果为有效整数时对其进行转换。 For sample: 样品:

var values = _session.CreateSQLQuery("SELECT Id FROM SomeTable").List();
var ids = new List<int>();

foreach (var item in values)
{
   if (item != null)
      ids.Add(Convert.ToInt32(item));
}

If this is a mapped table on the nhibernate scope, you could use LINQ to do this, for sample: 如果这是nhibernate范围内的映射表,则可以使用LINQ进行此操作,例如:

var ids = session.Query<SomeEntity>().Select(x => x.Id).ToList();

I know you are not using IQueryOver , but it is simpler, dynamic and cleaner than the way you are doing this now. 我知道您没有使用IQueryOver ,但是它比您现在执行的方式更简单,动态且更干净。

public IList<TReturn> GetValues<TEntity, TReturn>(IProjection column, Junction where, int top) where TEntity : BaseEntity
{
    IQueryOver<TEntity> query = null;
    if(where == null)
        query = session.QueryOver<TEntity>().Select(column);
    else
        query = session.QueryOver<TEntity>().Select(column).Where(where);

    IList<TReturn> instance = null;
    if(top == 0)
        instance = query.List<TReturn>();
    else
        instance = query.Take(top).List<TReturn>();
    return instance;
}

TEntity in above code is entity that represent (mapped to) your table. 上面代码中的TEntity是表示(映射到)表的实体。 Note that this is just to build the query. 请注意,这只是建立查询。 It will NOT return Entity. 它不会返回实体。

TReturn is the return type. TReturn是返回类型。 This can be any standard data type like int in your case. 这可以是任何标准数据类型,例如int

IProjection column parameter is the name of the column you want to select. IProjection column参数是您要选择的列的名称。

Junction where parameter allows you to specify the filter on rows if any. Junction where参数允许您在行上指定过滤器(如果有)。 To retrieve all rows, pass it null . 要检索所有行,请将其传递为null

Following is the way you call it: 以下是您的称呼方式:

Junction where = Restrictions.Conjunction();
where.Add(Restrictions.Eq(..........));

IList<int> idList = GetValues<SomeTableEntity, int>(Projections.Property<SomeTableEntity>(x => x.Id), where, 0);

This way, you avoid writing hard-coded SQL query as string in your code. 这样,您可以避免在代码中将硬编码的SQL查询作为字符串编写。 As you can see, this function can be used with any Entity (table) and any column. 如您所见,此函数可以与任何实体(表)和任何列一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NHibernate:如何使用带有本机 SQL 的 CreateSQLQuery 返回标量值? - NHibernate: How to return scalar value using CreateSQLQuery with native SQL? 使用CreateSQLQuery Nhibernate - Using CreateSQLQuery Nhibernate NHibernate:将createSQLQuery与一对一映射一起使用会导致额外的查询 - NHibernate: Using createSQLQuery with one-to-one mapping causing extra queries 执行UPDATE并返回使用NHibernate CreateSQLQuery方法刚刚更新的记录? - Execute UPDATE and return the record just updated using NHibernate CreateSQLQuery method? 在NHibernate中将CreateSQLQuery与INSERT查询一起使用 - Using CreateSQLQuery with INSERT query in NHibernate 使用nHibernate的CreateSQLQuery时如何保留列顺序? - How to preserve the columns order when using nHibernate's CreateSQLQuery? NHibernate CreateSQLQuery - NHibernate CreateSQLQuery NHibernate CreateSQLQuery返回具有填充属性的对象列表(即,渴望加载) - NHibernate CreateSQLQuery return list of objects with populated properties (i.e. eager loading) 如何使用Fluent NHibernate从另一张表中获取一列 - How to fetch one column from another table using Fluent NHibernate 当CacheMode = Ignore时,为什么NHibernate.ISession.CreateQuery返回与CreateSQLQuery不同的东西? - Why would NHibernate.ISession.CreateQuery return something different from CreateSQLQuery when CacheMode=Ignore?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM