0
votes

I have a basic NHibernate.Linq query:

var items = from item in session.Linq<ObjectType>()
             where item.ID > 0
             select new { ID = item.ID, Type = item.ClassName };

This works fine. However, ObjectType is a heavy-weight class, and I only want ID and ClassName. So I've created a DTO called EntityInfo:

public class EntityInfo
{
    public String ID { get; set; }
    public String Type { get; set; }
}

And I want to return an IEnumerable<EntityInfo>:

return from item in session.Linq<ObjectType>()
       select new EntityInfo() { ID = item.ID.ToString(), Type = item.ClassName };

Upon attempting to iterate through the returned IEnumerable, though, I get the following exception:

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
    at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
    at System.ThrowHelper.ThrowArgumentOutOfRangeException()
    at System.SZArrayHelper.get_Item[T](Int32 index)
    at System.Collections.ObjectModel.ReadOnlyCollection`1.get_Item(Int32 index)
    at NHibernate.Linq.Visitors.SelectArgumentsVisitor.VisitMethodCall(MethodCallExpression expr)
    at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.ExpressionVisitor.VisitList(ReadOnlyCollection`1 original)
    at NHibernate.Linq.Visitors.ExpressionVisitor.VisitNew(NewExpression nex)
    at NHibernate.Linq.Visitors.SelectArgumentsVisitor.VisitNew(NewExpression expr)
    at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.RootVisitor.HandleSelectCall(MethodCallExpression call)
    at NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression expr)
    at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.NHibernateExpressionVisitor.Visit(Expression exp)
    at NHibernate.Linq.Visitors.NHibernateQueryTranslator.Translate(Expression expression, QueryOptions queryOptions)
    at NHibernate.Linq.NHibernateQueryProvider.TranslateExpression(Expression expression)
    at NHibernate.Linq.NHibernateQueryProvider.Execute(Expression expression)
    at NHibernate.Linq.Query`1.GetEnumerator()

Is ToString() not allowed inside the select statement? I've gotten around it by running the original query, then creating a new enumerable by manually mapping the anonymous type to EntityInfo instances, but I'd obviously prefer the previous version.

For reference, I'm using NHibernate.Linq 1.0.0.4000, NHibernate 2.1.0.4000, and FluentNHibernate 1.0.0.593.

2

2 Answers

1
votes

Did you mean to use object initializer, instead of an array initializer?

return from item in session.Linq<ObjectType>()
   select new EntityInfo() { ID = item.ID.ToString(), Type = item.ClassName };
0
votes

I have same problem with .ToString(), It seems it is not allowed in LINQ-to-NHibernate query. My work-around was not just comparing numerical values. For your problem I suggest using following class and query:

public class EntityInfo
{
private String _id;    
public int ID { 
get {return _id.ToString();}
set {_id = Convert.ToInt32(value);}; 
}
    public String Type { get; set; }
}

return from item in session.Linq<ObjectType>()
       select new EntityInfo() { item.ID, item.ClassName };