代码之家  ›  专栏  ›  技术社区  ›  wusher

nhibernate是否可以将查询作为IDictionary而不是实体类返回?

  •  8
  • wusher  · 技术社区  · 16 年前

    public class Person
    {
       public virtual int Id {get; set; }
       public virtual string FirstName { get; set; }
       public virtual string MiddleName { get; set; }
       public virtual string LastName { get; set; }
    }
    

    使用映射:

    public class PersonMap
    {
       public PersonMap()
       {
           Table(TABLE_NAME); 
           Id( x => x.Id);
           Map(x => x.FirstName).Not.Nullable();
           Map(x => x.LastName).Not.Nullable();
           Map(x => x.MiddleName).Not.Nullable();
        }
    }
    

    我希望Nhibernate返回字典而不是实体:

    IDictionary<string,string> person = session.Get(id);//????
    string firstName = person["FirstName"];
    

    6 回复  |  直到 16 年前
        1
  •  12
  •   DanP    16 年前

    您需要定义自己的ResultTransformer实现,才能按需要的方式工作。下面是一个参考实现,您可以根据需要进行调整。完全没有错误检查等;因此请谨慎使用;)

    using System;
    using System.Collections;
    using NHibernate;
    using NHibernate.Properties;
    using NHibernate.Transform;
    
    
    [Serializable]
    public class DictionaryResultTransformer : IResultTransformer
    {
    
            public DictionaryResultTransformer()
            {
    
            }
    
            #region IResultTransformer Members
    
            public IList TransformList(IList collection)
            {
                    return collection;
            }
    
            public object TransformTuple(object[] tuple, string[] aliases)
            {
              var result = new Dictionary<string,object>();
              for (int i = 0; i < aliases.Length; i++)
              {
                result[aliases[i]] = tuple[i];                         
              }
              return result;
            }
    
            #endregion
    }
    
        2
  •  2
  •   Wayne    16 年前
    session.CreateCriteria<Person>()
    .SetResultTransformer(NHibernate.Transform.Transformers.AliasToEntityMap) 
    .List<Hashtable>();
    

    像这样的?

        3
  •  2
  •   Michael come lately PhiLho    8 年前

    你不需要 DictionaryResultTransformer 那个 DanP posted. AliasToEntityMapTransformer

    我找到的唯一方法是单独规划每个属性。不管你怎么想 那个

    var criteria = DetachedCriteria.For<Person>();
    criteria.Add(Restrictions.Eq("Id", id));
    var projectionList = Projections.ProjectionList();
    var metadata = session.SessionFactory.GetClassMetadata(typeof(Person));
    foreach (var name in metadata.PropertyNames)
    {
        projectionList.Add(Projections.Property(name), name);
    }
    criteria
        .SetProjection(projectionList)
        .SetResultTransformer(Transformers.AliasToEntityMap);
    var result = criteria.GetExecutableCriteria(session)
        .UniqueResult<IDictionary>()
    

    在上面的示例中,我使用一个查询来模拟 Get . 当然,您可以对此进行一点更改,然后返回一个集合;只需调用 List<T> 而不是 UniqueResult<T>

        4
  •  1
  •   Jamie Ide    16 年前

    不需要,但是通过将逻辑封装在存储库方法中,您可以很容易地实现这一点。

    public IDictionary<string, string> GetPersonDictionary(int id)
    {
        var person = session.Get<Person>(id);
        var dict = new Dictionary<string, string>();
        dict.Add("FirstName", person.FirstName);
        /// etc.
        return dict;
    }
    

    您还可以使用反射来填充字典。

        5
  •  0
  •   user333306 user333306    16 年前

    请看这篇博文:

    http://sdesmedt.wordpress.com/2006/09/04/nhibernate-part-4-mapping-techniques-for-aggregation-one-to-many-mapping/

    如果你想要一个具体的例子,检查这个不错的教程的样本。查看非实体且具有自定义映射逻辑的摘要:

    http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

    SETRESULT变压器 仅此而已,变换会产生另一个对象或集合。包括我的字典。

        6
  •  0
  •   Community Mohan Dere    9 年前

    您可以通过执行客户端linq投影来实现这一点,请参见Diego对 this post