2012-02-13 5 views
4

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

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

я получил следующее исключение:

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

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

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

Bd выглядеть:

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, 
) 
+0

Не могли бы вы указать свойства сущностей и их отношения или структуру таблиц? –

+0

Я добавил исходный код –

ответ

1

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

DictionaryItem statusAlias = null; 
User userAlias = null; 
return Session.QueryOver<User>(() => userAlias) 
    .JoinAlias(() => userAlias.LoginStatus,() => statusAlias) 
    .Where(() => statusAlias.Code == "") 
    .ToList(); 
+0

Вместо LoginStatus statusAlias ​​= null; должно быть через DictionaryItem statusAlias ​​= null; Ваш запрос выглядит очень удивительно для меня, вы можете объяснить? У меня есть следующее исключение: «не ассоциация: LoginStatus» –

+0

@Adam, проверьте соответствие между двумя объектами, определенными в файле '.hbm', и для запроса вы должны выполнить псевдоним объекта' DictionayItem', чтобы разрешить их собственности и использовать их, см. раздел ассоциации в этой странице: http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx. –

+0

Во-первых, спасибо за ссылку. Ваш запрос отлично работает, когда у меня есть такое сопоставление для свойства LoginStatus: Ссылки (x => x.LoginStatus); но когда у меня есть Map (x => x.LoginStatus) .CustomType (); есть исключение с assosaction: «не ассоциация: LoginStatus». Я думаю, что это может быть правильное поведение nhiberante, потому что LoginStatus отображается как значение Int, нет информации о связи со статьей словаря. Если вы думаете иначе, как я, я могу создать образец проекта и отправить вам, потому что это очень любопытный случай для меня. –

0

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

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

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

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(); 
+0

К сожалению, я знаю, чего хочу. Я не хочу использовать сопоставление ссылок для свойства типа DictionaryItem, потому что каждый раз, когда я называю это свойство, стрельба придет к dadabase, и поэтому я wany mapping в моем настраиваемом типе из repostiory, я также знаю, что могу удалить свой собственный тип, и добавить сопоставление ссылок и использовать кеш второго уровня для не снимать данные словаря словаря, но я хочу использовать свой собственный тип;) –