поиск по столбцу типа пользователя в nhibernate

У меня есть объект User, который содержит свойство Status типа DictionaryItem, и оно отображается как UserType. Теперь я хочу сделать следующий оператор linq:

Session.Query<User>().Where(x => x.LoginStatus.Code == "").ToList();

У меня следующее исключение:

Дополнительная информация: не удалось разрешить свойство: Код: пользователя

Я знаю, что проблема в том, что я выполняю поиск, используя свой собственный тип (код свойства существовал для моего DictionaryItem типа пользователя). Запрос сеанса nhibernate генерирует оператор SQL, когда я вызываю ToList(), но LoginStatus не является ссылочным типом, а только типом User, есть ли обходной путь для выполнения запроса по типу пользователя?

Изменить 1: Ниже исходного кода:

    public class User
{
    public virtual Guid Id { get; set; }
    public virtual DictionaryItem LoginStatus { get; set; }

    public User()
    {
    }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.Id);
        Map(x => x.LoginStatus).CustomType<DictionaryItemCustomType>();
    }
}
public class DictionaryItem
    {
        public virtual int Id { get; set; }
        public virtual string Code { get; set; }
        public virtual string Description { get; set; }
    }
 public class DictionaryItemCustomType : IUserType
    {
        public new bool Equals(object x, object y)
        {
            if (x == null && y == null)
            {
                return true;
            }
            if (x == null || y == null)
            {
                return false;
            }
            return ((DictionaryItem)x).Id == ((DictionaryItem)y).Id;
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            object value = NHibernateUtil.Int32.NullSafeGet(rs, names);
            if (value == null)
            {
                return null;
            }

            return AutofacServiceHostFactory.Container.Resolve<IDictionaryRepository>().DictionaryItems.First(x => x.Id == (int)value);
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            DictionaryItem dictionaryItem = value as DictionaryItem;
            NHibernateUtil.Int32.NullSafeSet(cmd, dictionaryItem == null ? (object)null : dictionaryItem.Id, index);
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public object Replace(object original, object target, object owner)
        {
            return DeepCopy(original);
        }

        public object Assemble(object cached, object owner)
        {
            throw new NotImplementedException();
        }

        public object Disassemble(object value)
        {
            throw new NotImplementedException();
        }

        public SqlType[] SqlTypes
        {
            get { return new[] { NHibernateUtil.Int32.SqlType }; }
        }

        public Type ReturnedType
        {
            get { return typeof(DictionaryItem); }
        }

        public bool IsMutable
        {
            get { return false; }
        }
    }

Бд выглядят так:

CREATE TABLE [dbo].[User](
    [Id] [uniqueidentifier] NOT NULL,   
    [LoginStatusId] [int] NOT NULL
)

CREATE TABLE [dbo].[DictionaryItem](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Code] [nvarchar](20) NOT NULL,
    [Description] [nvarchar](200) NOT NULL,
)

person Adam Łepkowski    schedule 13.02.2012    source источник
comment
Не могли бы вы опубликовать свойства сущностей и их отношения или структуру таблиц?   -  person Mahmoud Gamal    schedule 13.02.2012
comment
Я добавил исходный код   -  person Adam Łepkowski    schedule 13.02.2012


Ответы (2)


Попробуй это:

DictionaryItem statusAlias = null;
User userAlias = null;
return Session.QueryOver<User>(() => userAlias)
    .JoinAlias(() => userAlias.LoginStatus, () => statusAlias)
    .Where(() => statusAlias.Code == "")
    .ToList();
person Mahmoud Gamal    schedule 13.02.2012
comment
Вместо LoginStatus statusAlias ​​= null; должен быть DictionaryItem statusAlias ​​= null; Мне ваш вопрос очень интересен, вы можете объяснить? У меня есть следующее исключение, а не ассоциация: LoginStatus - person Adam Łepkowski; 13.02.2012
comment
@Adam, проверьте свое сопоставление между двумя объектами, определенными в файле .hbm, и для запроса вы должны указать псевдоним объекта DictionayItem, чтобы разрешить их свойство и использовать их, см. Раздел ассоциации на этой странице: nhforge.org/blogs/nhibernate/archive/2009 / 12/17 /. - person Mahmoud Gamal; 14.02.2012
comment
Во-первых, спасибо за ссылку. Ваш запрос отлично работает, когда у меня есть такое сопоставление для свойства LoginStatus: Ссылки (x = ›x.LoginStatus); но когда у меня есть карта (x = ›x.LoginStatus) .CustomType ‹DictionaryItemCustomType› (); есть исключение с assosaction: not an association: LoginStatus. Я думаю, что это может быть правильным поведением nhiberante, потому что LoginStatus отображается как значение Int, нет информации о связи с таблицей элементов словаря. Если вы думаете иначе, чем я, я могу создать образец проекта и отправить вам, потому что для меня это очень любопытный случай. - person Adam Łepkowski; 14.02.2012
comment
Запрос, который отлично работает с моим кодом, выглядит так: Session.Query ‹User› () .Where (x = ›x.LoginStatus == IDictionaryRepository.GetByCode (здесь код)). ToList (); - person Adam Łepkowski; 14.02.2012

Ваше отображение неверно. DictionaryItem не следует отображать как настраиваемый тип. Для меня это похоже на другую сущность.

Map(x => x.LoginStatus).CustomType<DictionaryItemCustomType>();

Вышеуказанное указывает на то, что вы хотите отобразить только один столбец. Вы хотите сопоставить фактическую сущность DictionaryItem с User. Вам нужно сделать что-то вроде этого:

References(x => x.LoginStatus, "LoginStatusId");

Затем вам нужно сопоставить DictionaryItem:

public class DictionaryItemMap : ClassMap<DictionaryItem>
{
    public DictionaryItemMap()
    {
        Id(x => x.Id);  //You'll need to do something else here for identity columns
        Map(x => x.Code);
        Map(x => x.Description);
    }
}

После того, как у вас есть это сопоставление, вы можете выполнить упомянутый выше запрос с помощью MGA.

LoginStatus statusAlias = null;
User userAlias = null;
return Session.QueryOver<User>(() => userAlias)
    .JoinAlias(() => userAlias.LoginStatus, () => statusAlias)
    .Where(() => statusAlias.Code == "")
    .ToList();
person Cole W    schedule 13.02.2012
comment
К сожалению, я знаю, чего хочу. Я не хочу использовать сопоставление ссылок для свойства типа DictionaryItem, потому что каждый раз, когда я вызываю это свойство, снимок будет приходить в dadabase, и поэтому я хочу сопоставить свой настраиваемый тип из репозитория, я также знаю, что могу удалить свой настраиваемый тип, и добавить сопоставление ссылок и использовать кеш 2-го уровня, чтобы не снимать данные элемента словаря, но я хочу использовать свой собственный тип;) - person Adam Łepkowski; 14.02.2012