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

nhibernate是否可以将查询作为IDictionary而不是实体类返回?,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有一个实体人: 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 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"];
IDictionary person=session.Get(id);/????
字符串firstName=person[“firstName”];

这是否可以在不添加其他映射的情况下实现?

请查看此博客文章:

如果您想要一个具体的例子,请查看本教程的示例。查看非实体且具有自定义映射逻辑的摘要:


或者在google上搜索只用于此目的的SetResultTransformer,在其他对象或集合中转换结果。包括我的字典

没有,但是您可以通过将逻辑封装在存储库方法中轻松实现这一点

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;
}
public-IDictionary GetPersonDictionary(int-id)
{
var person=session.Get(id);
var dict=新字典();
dict.Add(“名字”,person.FirstName);
///等等。
返回命令;
}
您还可以使用反射来填充字典。

session.CreateCriteria()
session.CreateCriteria<Person>()
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToEntityMap) 
.List<Hashtable>();
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToEntityMap) .List();

类似这样的事情?

您可以通过执行客户端linq投影来实现,请参阅Diego的答案。

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

使用系统;
使用系统集合;
使用NHibernate;
使用NHibernate。性质;
使用NHibernate.Transform;
[可序列化]
公共类字典ResultTransformer:IResultTransformer
{
公共字典ResultTransformer()
{
}
#区域变压器成员
公共IList转换列表(IList集合)
{
回收;
}
公共对象转换元组(对象[]元组,字符串[]别名)
{
var result=newdictionary();
for(int i=0;i
您不需要
字典ResultTransformer
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>()
var-criteria=DetachedCriteria.For();
标准。添加(限制。等式(“Id”,Id));
var projectionList=Projections.projectionList();
var metadata=session.SessionFactory.GetClassMetadata(typeof(Person));
foreach(metadata.PropertyNames中的变量名)
{
projectionList.Add(Projections.Property(name)、name);
}
标准
.SetProjection(投影列表)
.SetResultTransformer(Transformers.AliasToEntityMap);
var result=criteria.GetExecutableCriteria(会话)
.UniqueResult()

在上面的示例中,我使用一个查询来模拟
Get
。当然,您可以对此稍作更改并返回一个集合;只需调用
List
而不是
UniqueResult

即可。您能否提供一个使用结果转换器填充字典的示例?我认为不编写自定义的IResultTransformer是不可能的。是的,您必须编写代码。编写干净的代码有时需要更多的努力。这与我想做的非常接近。问题是每个哈希表中都有一个键值对,其中person对象是值。我试图得到一个哈希表,其中每个属性都是一个键值对;但是,我认为不可能使用投影为列名及其值创建KeyValuePair。@Maudite:好的。我明白你的意思了。让我用一个示例result transformer impl发布一个新答案。非常干净的解决方案。杰出的如何从查询中使用它?您可以显示用法吗?@emirhosseini-用法类似于:session.CreateSQLQuery(“从产品p中选择p.Name、p.Price、p.ProductId”).SetResultTransformer(新字典ResultTransformer()).List();
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>()