2012-12-19 12 views
5

Ho trovato una dozzina di domande simili alle mie ma nessuna di esse ha offerto una soluzione al mio problema.nhibernate, impossibile risolvere la proprietà QueryOver solo una tabella

Grazie in anticipo

Ok,

ho questa classe

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

questa è la mappatura ....

<?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> 

e questo è come sono chiamandolo

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

errore ... { "Impossibile risolvere proprietà: E-mail del: Domain.User.User"}

StackTrace ...

a NHibernate.Persister.Entity.AbstractPropertyMapping.ToType (String propertyName) a NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber (String propertyPath) a NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns (String alias, String propertyName) a NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns (alias stringa, String propertyName) presso NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns (sottocriteri ICriteria, String propertyName) a NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection (sottocriteri ICriteria, String propertyName) a NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName (ICriteriaQuery criteriaQuery, criteri ICriteria, stringa propertyName, Object value, ICriterion critertion) a NHibernate.Criterion.SimpleExpression.ToSqlString (criteri ICriteria, ICriteriaQuery criteriaQuery, IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary 2 enabledFilters) a NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor (IOuterJoinLoadable persister, CriteriaQueryTranslator traduttore, ISessionFactoryImplementor factory, Criteri ICriteria, String rootEntityName, IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary 2 enabledFilters) presso NHibe rnate.Impl.SessionImpl.List (criteri CriteriaImpl, risultati IList) a NHibernate.Impl.CriteriaImpl.List (risultati IList) a NHibernate.Impl.CriteriaImpl.UniqueResultT a NHibernate.Criterion.QueryOver 1.SingleOrDefault() at NHibernate.Criterion.QueryOver 1.NHibernate.IQueryOver. SingleOrDefault() a DataObjects.NHibernate.UserRepository.FindByEmail (String emailAddress) in E: \ Projects \ DataObjects.NHibernate \ UserRepository.cs: linea 26 a Castle.Proxies.Invocations.IUserRepository_FindByEmail.InvokeMethodOnTarget() a Castle.DynamicProxy .AbstractInvocation.Proceed() su Castle.Facilities.AutoTx.TransactionInterceptor.SynchronizedCase (invocazione IInvocation, transazione ITransaction) in d: \ BuildAgent-03 \ work \ 9844bdf039249947 \ src \ Castle.Facilities.AutoTx \ TransactionInterceptor.cs: riga 137

MODIFICA:

OK. Risolto in una certa misura. Ho modificato tutti i miei nomi di proprietà e componenti in maiuscolo nella mia mappatura. Invece di ...

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

impostarlo su ...

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

e funziona. Ora, è una garanzia che NHibernate stia popolando/leggendo le mie proprietà attraverso i campi? Lo spero.

risposta

3

Questo dovrebbe aiutare: Modificare le impostazioni di essere diverso per ottenere e impostare

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

e mappare le proprietà:

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

NHibernate utilizzerà campo per il set e la proprietà dimenticare. Questo QueryOver:

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

... funzionerà ora

+0

Ciao Radim, è esattamente quello che ho fatto. Funziona bene. Grazie –

2

Credo che il "nome" delle proprietà nella propria mappatura debba corrispondere al caso delle proprietà virtuali pubbliche della classe. Prova a cambiare <property name="email"... a <property name="Email"... e così via.

+0

Credo che il valore di default per l'attributo default-accesso nella mappatura è di proprietà, ma la mia dice campo. C'è la comodità di averlo impostato sulla proprietà ed eliminare tutti i campi privati ​​dalla mia classe? –

+0

@Tony - Sì, è conveniente eseguire il mapping della proprietà automatica ignorando il campo, tuttavia si consideri che [le proprietà automatiche possono essere un odore di codice] (http://blog.ploeh.dk/2011/05/26/CodeSmellAutomaticProperty. aspx). – eulerfx

+0

Sicuramente voglio utilizzare l'accesso al campo a causa di Null Pattern che sto pensando di utilizzare. Inoltre, l'idea di auto-proprietà non sembra troppo buona per le mie orecchie. Ho dimenticato di aggiungere che sto usando un approccio DDD per scrivere la mia applicazione, quindi gli oggetti di dominio con setter nelle loro proprietà sono un NO-NO. –

Problemi correlati