2012-12-19 18 views
5

Znalazłem kilkanaście pytań podobnych do moich, ale żaden z nich nie zaproponował rozwiązania mojego problemu.nhibernate, nie można rozwiązać właściwości QueryOver tylko jedna tabela

góry dziękuję

Ok,

mam tej klasy

public class User : IEntity 
    { 
     private int id; 
     public virtual int Id { get { return id; } } 


     private string email; 

     public virtual string Email 
     { 
      get { return email; } 
      //private set { email = value; } 
     } 

     private string password; 

     public virtual string Password 
     { 
      get { return password; } 
      //private set { password = value; } 
     } 

     private bool isActive; 

     public virtual bool IsActive 
     { 
      get { return isActive; } 
      //private set { isActive = value; } 
     } 

     private bool isRegistered; 

     public virtual bool IsRegistered 
     { 
      get { return isRegistered; } 
      //private set { isRegistered = value; } 
     } 

     private bool hasRequestedApplication; 

     public virtual bool HasRequestedApplication 
     { 
      get { return hasRequestedApplication; } 
      //private set { hasRequestedApplication = value; } 
     } 


     private ContactInfo contactInformation; 

     public virtual ContactInfo ContactInformation 
     { 
      get { return contactInformation; } 
      //private set { contactInformation = value; } 
     } 



     public User(string email) 
     { 
      this.email = email; 
     } 

     public User(string email, string password):this(email) 
     { 
      this.password = password; 
     } 

     public User() 
     { } 
} 

to odwzorowanie ....

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" 
       namespace="Domain.User" default-access="field"> 

    <class name="User" table="[User]"> 

    <id name="id" column="UserID"> 
     <generator class="identity" /> 
    </id> 
    <property name="email" column="Email" not-null="true"></property> 
    <property name="password" column="HashedPassword" not-null="false"></property> 
    <property name="isRegistered" column="IsRegistered" not-null="true"></property> 
    <property name="isActive" column="IsActive" not-null="true"></property> 
    <property name="hasRequestedApplication" column="HasRequestedApplication" not-null="true"></property> 

    <one-to-one name="contactInformation" class="Domain.User.ContactInfo"/> 
    </class> 
</hibernate-mapping> 

i to, jaki jestem wywołanie go:

public class UserRepository: IUserRepository 
    { 
     Func<ISession> session; 

     public UserRepository(Func<ISession> _session) 
     { 
      session = _session; 
     } 

     [Transaction] 
     public User FindByEmail(string emailAddress) 
     { 
      using (var tx = session()) 
      { 
       return tx.QueryOver<User>().Where(u => u.Email == emailAddress).SingleOrDefault(); 
      } 
     } 
} 

... {Błąd "Nie można rozwiązać właściwość: E-mail: Domain.User.User"}

StackTrace ...

na NHibernate.Persister.Entity.AbstractPropertyMapping.ToType (string propertyName) w NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber (ciąg propertyPath) w NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns (znany ciąg, String propertyName) w NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns (alias String String propertyName) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns (podkryteria ICriteria, String propertyName) na NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection (podkryteriów ICriteria, String propertyName) na NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName (ICriteriaQuery criteriaQuery kryteria ICriteria, ciąg propertyName wartość obiektu, ICriterion critertion) w NHibernate.Criterion.SimpleExpression.ToSqlString (kryteria ICriteria, ICriteriaQuery criteriaQuery, IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary 2 enabledFilters) w NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor (IOuterJoinLoadable persister, CriteriaQueryTranslator translator ISessionFactoryImplementor fabryka, kryteria ICriteria, String rootEntityName, IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary 2 enabledFilters) w NHibe rnate.Impl.SessionImpl.List (kryteria CriteriaImpl wyniki IList) w NHibernate.Impl.CriteriaImpl.List (wyniki IList) w NHibernate.Impl.CriteriaImpl.UniqueResultT w NHibernate.Criterion.QueryOver 1.SingleOrDefault() at NHibernate.Criterion.QueryOver 1.NHibernate.IQueryOver. SingleOrDefault() na DataObjects.NHibernate.UserRepository.FindByEmail (String EMAILADDRESS) w E: \ Projects \ DataObjects.NHibernate \ UserRepository.cs: linia 26 na Castle.Proxies.Invocations.IUserRepository_FindByEmail.InvokeMethodOnTarget() w Castle.DynamicProxy .AbstractInvocation.Proceed() at Castle.Facilities.AutoTx.TransactionInterceptor.SynchronizedCase (Inwokacja IInokacja, transakcja ITransaction) w katalogu d: \ BuildAgent-03 \ work \ 9844bdf039249947 \ src \ Castle.Facilities.AutoTx \ TransactionInterceptor.cs: wiersz 137

EDYTOWANIE:

OK. Rozwiązany do pewnego stopnia. Zmieniłem wszystkie moje właściwości i nazwy komponentów na kapitał w moim mapowaniu. Zamiast ...

<property name="email" column="emailaddress" /> 

ustawić ...

<property name="Email" column="emailaddress" /> 

i to działa. Czy jest to gwarancja, że ​​NHibernate zapełni/odczytuje moje właściwości za pośrednictwem pól? Mam nadzieję.

Odpowiedz

3

To powinno pomóc: Zmień ustawienia, aby być różny dla dostać i ustawić

<hibernate-mapping ... default-access="field.camelcase"> 

i mapowania właściwości:

<property name="Email" column="emailaddress" /> 

NHibernate użyje pole do zestawu i właściwość dla zdobycia. Ten QueryOver:

return tx.QueryOver<User>()  
    .Where(u => u.Email == emailAddress) 
    .SingleOrDefault(); 

... będzie działać teraz

+0

Witaj Radim, Dokładnie to zrobiłem. Działa dobrze. Dzięki –

2

Uważam, że "nazwa" właściwości w mapowaniu powinna pasować do przypadku publicznych wirtualnych właściwości w klasie. Spróbuj zmienić <property name="email"... na <property name="Email"... i tak dalej.

+0

myślę domyślna wartość atrybutu default-dostępowego w mapowaniu jest własność, ale mina mówi pole. Czy jest wygoda, aby ustawić ją na własność i wyeliminować wszystkie prywatne pola z mojej klasy? –

+0

@ Tony - tak, wygodnie jest robić mapowanie właściwości automatycznych z pominięciem pola, ale należy wziąć pod uwagę, że [auto-właściwości może być zapachem kodu] (http://blog.ploeh.dk/2011/05/26/CodeSmellAutomaticProperty. aspx). – eulerfx

+0

Zdecydowanie chcę korzystać z dostępu do pola, ponieważ planuję użyć wzoru zerowego. Także idea auto-właściwości nie brzmi zbyt dobrze dla mojego słyszenia. Zapomniałem dodać, że używam metody DDD do napisania mojej aplikacji, więc obiekty domenowe z ustawiaczami w ich właściwościach są NIE-NIE. –