query left c# nhibernate nhibernate-criteria

c# - left - Asociaciones de transformadores NHibernate AliasToBean



nhibernate query (2)

Estoy tratando de usar la siguiente declaración para obtener una entidad con los campos que estoy buscando:

retVal = session.CreateCriteria(typeof(MyEntity)) .CreateAlias("MyEntityProperty", "MyEntityProperty") .Add(Restrictions.Eq("MyEntityProperty.Year", year)) .SetProjection( Projections.Distinct( Projections.ProjectionList() .Add(Projections.Property("Property1"), "Property1") .Add(Projections.Property("Property2"), "Property2") .Add(Projections.Property("MyEntityProperty.RegisteredUser"), "MyEntityProperty.RegisteredUser") .Add(Projections.Property("MyEntityProperty.CompanyInfo"), "MyEntityProperty.CompanyInfo") ) ) .SetResultTransformer(Transformers.AliasToBean(typeof(MyEntity))) .List<MyEntity>() .Cast<BaseMyEntity>();

MyEntity es la entidad que quiero devolver, y MyEntityProperty es una propiedad de MyEntity que es otra entidad (de tipo MyEntityProperty).

El error que recibo es Could not find a setter for property ''MyEntityProperty.RegisteredUser'' in class ''MyEntity'' se Could not find a setter for property ''MyEntityProperty.RegisteredUser'' in class ''MyEntity''

¿El transformador AliasToBean no puede manejar subentidades? ¿O hay algo más que debo hacer para que funcione?


Bueno, no estaba haciendo las cosas más complicadas de lo necesario.

En lugar de tratar de establecer los campos en la entidad secundaria, todo lo que tenía que hacer era hacer referencia al campo de la entidad en sí:

.Add(Projections.Property("MyEntityProperty"), "MyEntityProperty")

y nHibernate lo poblaba bien.

Pero me alegro de haberlo preguntado porque obtuve el código muy útil de Radim :-)


Está mi obra maestra ... que estoy usando para transformar cualquier nivel de profundidad de proyección. Tómalo y úsalo así:

.SetResultTransformer(new DeepTransformer<MyEntity>())

Se podría usar para cualquier propiedad ValueType , referencias de many-to-one y también para objetos dinámicos ...

public class DeepTransformer<TEntity> : IResultTransformer where TEntity : class { // rows iterator public object TransformTuple(object[] tuple, string[] aliases) { var list = new List<string>(aliases); var propertyAliases = new List<string>(list); var complexAliases = new List<string>(); for(var i = 0; i < list.Count; i++) { var aliase = list[i]; // Aliase with the ''.'' represents complex IPersistentEntity chain if (aliase.Contains(''.'')) { complexAliases.Add(aliase); propertyAliases[i] = null; } } // be smart use what is already available // the standard properties string, valueTypes var result = Transformers .AliasToBean<TEntity>() .TransformTuple(tuple, propertyAliases.ToArray()); TransformPersistentChain(tuple, complexAliases, result, list); return result; } /// <summary>Iterates the Path Client.Address.City.Code </summary> protected virtual void TransformPersistentChain(object[] tuple , List<string> complexAliases, object result, List<string> list) { var entity = result as TEntity; foreach (var aliase in complexAliases) { // the value in a tuple by index of current Aliase var index = list.IndexOf(aliase); var value = tuple[index]; if (value.IsNull()) { continue; } // split the Path into separated parts var parts = aliase.Split(''.''); var name = parts[0]; var propertyInfo = entity.GetType() .GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); object currentObject = entity; var current = 1; while (current < parts.Length) { name = parts[current]; object instance = propertyInfo.GetValue(currentObject); if (instance.IsNull()) { instance = Activator.CreateInstance(propertyInfo.PropertyType); propertyInfo.SetValue(currentObject, instance); } propertyInfo = propertyInfo.PropertyType.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); currentObject = instance; current++; } // even dynamic objects could be injected this way var dictionary = currentObject as IDictionary; if (dictionary.Is()) { dictionary[name] = value; } else { propertyInfo.SetValue(currentObject, value); } } } // convert to DISTINCT list with populated Fields public System.Collections.IList TransformList(System.Collections.IList collection) { var results = Transformers.AliasToBean<TEntity>().TransformList(collection); return results; } }