Есть ли какие-то соображения при сравнении Enums в LINQ-to-NHibernate или LINQ? - PullRequest
3 голосов
/ 27 февраля 2010

В таком запросе:

var q = from l in session.Linq<Letter>()
    where
    letterTypeSearch == null ? true : 
        (l.LetterType.ToString() == letterTypeSearch)

l.LetterType - это Enum.

UPDATE Кажется, невозможно сравнить Enums в текущем linq-to-nhibernate. Хотя letterTypeSearch является строкой, содержащей экземпляр LetterType, который ToString() ed, а LetterType наследуется от int, существует 3 способа сравнения:

1- Сравнение в String: невозможно, поскольку l.LetterType.ToString() производит "(ArgumentOutOfRangeException): индекс вышел за пределы диапазона. Должен быть неотрицательным и меньше размера коллекции. Имя параметра: индекс, «ошибка».

2- Сравнение в самом Enum (LetterType): это невозможно, потому что l.LetterType == LetterType.Internal приводит к "(QueryException): несоответствие типов в NHibernate.Criterion.SimpleExpression: ожидаемый тип LetterType System.Int32, фактический тип Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities.LetterType, "ошибка.

3- Сравнение в Int32: пока невозможно, поскольку Convert.ToInt32(l.LetterType) генерирует "(NotImplementedException): метод ToInt32 не реализован.," Ошибка.

Так как я могу сравнить Enums в LINQ-to-NHibernate? Эта проблема характерна для LINQ-to-NHibernate или у всех пользователей LINQ такая проблема?

UPDATE2 вот класс, enum и mapping (сммализованный):

    public class Letter
    {
        private LetterType _letterType;
        public LetterType LetterType
        {
            set
            {
                _letterType = value;
            }//end  
            get
            {
                return _letterType;
            }//end  
        }
}

=========

public enum LetterType { Входящий = 0, Исходящий = 1, Внутренний = 2, }

=========

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
  <class
       name="Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities.Letter,Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities"
        table="OfficeAutomation_Letter">

    <property
         name="LetterType" column="LetterType"
         type="int" update="true" insert="true" access="property"
         not-null="true"/>

  </class>
</hibernate-mapping>

Ответы [ 2 ]

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

Вы отобразили enum как type="int", что вызывает ошибку, возможно потому, что нет неявных преобразований в и из int. Если вы удалите атрибут type, enum будет сопоставлен со значением int в базе данных, и запросы Linq будут работать.

Также обратите внимание, что в вашем сопоставлении свойств каждый атрибут, кроме имени и типа, не нужен, так как он задает значения по умолчанию. «Имя» является единственным обязательным атрибутом в сопоставлении свойств, см. Раздел свойство в справочной документации.

<property name="LetterType" />

Используя последнюю версию (2.1.2GA) NHibernate.Linq, доступную по ссылке NHibernate Core на nhforge.org , следующие запросы с перечислениями работают как ожидается.

var q = from l in session.Linq<Letter>()
    where l. LetterType == LetterType.A4
    select l;
var result = q.ToList<Letter>();

LetterType? ltype = LetterType.A4;
q = from l in session.Linq<Letter>()
    select l;
if (code != null) {
    q = q.Where( l => l.LetterType == ltype.Value );
}
result = q.ToList<Letter>();

Однако эта форма последнего запроса не будет работать, если ltype равен null, так как анализатор запросов по-прежнему будет пытаться использовать ltype.Value.

q = from l in session.Linq<Letter>()
    where ltype != null && l => l.LetterType == ltype.Value
    select l;
result = q.ToList<Letter>();
0 голосов
/ 27 февраля 2010

Если бы я был вами, я создал бы Enum из Dot net с этими nhibernate Enum, а затем сравнил их с точками net равно.

...