ArgumentOutOfRangeException с использованием ToString в запросе LINQ to NHibernate - PullRequest
0 голосов
/ 27 февраля 2010

У меня есть базовый запрос NHibernate.Linq:

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

Это отлично работает. Однако ObjectType является классом с большим весом, и мне нужны только ID и ClassName. Итак, я создал DTO с именем EntityInfo:

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

И я хочу вернуть IEnumerable<EntityInfo>:

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

Однако при попытке перебрать возвращенный IEnumerable я получаю следующее исключение:

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()

Разрешено ли ToString() внутри оператора select? Я справился с этим, запустив исходный запрос, затем создав новый перечислимый объект, вручную сопоставив анонимный тип с EntityInfo экземплярами, но я бы, очевидно, предпочел предыдущую версию.

Для справки я использую NHibernate.Linq 1.0.0.4000, NHibernate 2.1.0.4000 и FluentNHibernate 1.0.0.593.

Ответы [ 2 ]

1 голос
/ 27 февраля 2010

Вы имели в виду использовать инициализатор объекта вместо инициализатора массива?

return from item in session.Linq<ObjectType>()
   select new EntityInfo() { ID = item.ID.ToString(), Type = item.ClassName };
0 голосов
/ 27 февраля 2010

У меня такая же проблема с .ToString(), кажется, это не разрешено в запросе LINQ-to-NHibernate. Мой обходной путь - не просто сравнение числовых значений. Для вашей задачи я предлагаю использовать следующий класс и запрос:

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 };
...