NHibernate AliasToBean转换器关联

我正在尝试使用以下语句来获取具有我所追求的字段的实体:

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() .Cast(); 

MyEntity是我想要返回的实体,MyEntityProperty是MyEntity的一个属性,它是另一个实体(MyEntityProperty类型)。

我得到的错误是Could not find a setter for property 'MyEntityProperty.RegisteredUser' in class 'MyEntity'

AliasToBean转换器是否无法处理子实体? 或者还有什么我需要做的才能让它发挥作用?

有我的主要作品 ……我用它来改变任何级别的投影深度。 拿它并像这样使用它:

 .SetResultTransformer(new DeepTransformer()) 

它可以用于任何ValueType属性, many-to-one引用以及动态对象 ……

 public class DeepTransformer : IResultTransformer where TEntity : class { // rows iterator public object TransformTuple(object[] tuple, string[] aliases) { var list = new List(aliases); var propertyAliases = new List(list); var complexAliases = new List(); 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() .TransformTuple(tuple, propertyAliases.ToArray()); TransformPersistentChain(tuple, complexAliases, result, list); return result; } /// Iterates the Path Client.Address.City.Code  protected virtual void TransformPersistentChain(object[] tuple , List complexAliases, object result, List 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().TransformList(collection); return results; } } 

好吧,我不是把事情变得比必要的更复杂。

我不需要尝试在子实体上设置字段,而是引用实体字段本身:

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

和nHibernate填充它很好。

但我很高兴我问,因为我得到了Radim非常有用的代码:-)