开发者

NHIbernate: Shortcut for projecting all properties?

I'm trying to generate SQL along the lines of:

SELECT 
  t.*, 
  SELECT (...)
FROM Title t
[trimmed]

using QueryOver

Title title = null;

var q = session
   .QueryOver(() => title)
   .Select(
      Projections.Alias(Projections.Property<Title>(t => t.Id), "Id"),
      Projections.Alias(Projections.Property<Title>(t => t.Name), "Name"),
      ....
      Projections.SubQuery(sq.Where(tt => tt.Id == title.Id))), "TopLevelGenre")
)
[code trimmed]

There are 15 properties in Title that I would like to project. Is 开发者_如何学运维there an easier way of doing it so that I don't have to project each property individually as I've started to do above?


If you don't mind ICriteria, this works. I have tested with 2.1.2, but I can't see why if wouldn't work with 3.x.

var projectionList = Projections.ProjectionList();
var metadata = session.SessionFactory.GetClassMetadata(typeof(Title));
foreach (var name in metadata.PropertyNames)
{
    projectionList.Add(Projections.Property(name), name);
}
var criteria = DetachedCriteria.For<Title>()
   .SetProjection(projectionList)
   ...;


I've discovered that as of NHibernate 3.2, this is not possible without manually enumerating all of the properties.


It is not possible to do this without manually enumerating all of the properties. I usually use CodeSmith to generate projection codes.


If you want Title objects, you can just write:

IList<Title> list = session.QueryOver<Title>.Where(/*some condition*/).List();  

nHibernate will populate all of the Title attributes for you.
see here for further detail.


Is it possible to create a view on the title table with the columns that you are interested in? or Perhaps you may want to try splitting the properties of Title class across two classes (TitleBase class and Title class which is inherited from TitleBase class). Accordingly you need to create two separate mapping files.

Suppose if all the properties that you are interested in are in TitleBase class, then use it in the above mentioned query.


I have solved it with this code. I hope it can serve you. I just use Bags, just change comparison if you need to use ISet for example. PDM is Entity whose properties i am applying reflection over. You could change this method to be generic.

        ProjectionList list = Projections.ProjectionList();            
        var metadata = session.SessionFactory.GetClassMetadata(typeof(PDM));

        foreach (var name in metadata.PropertyNames)
        {
            PropertyInfo property = typeof(PDM).GetProperties(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name.Equals(name));
            FieldInfo field = typeof(PDM).GetFields(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name.Equals(name));

            if (property != null)
            {
                if (!property.PropertyType.Name.Contains("IList"))
                {
                    list.Add(Projections.Property(name), name);
                }
            }

            if (field != null)
            {
                if (!field.FieldType.Name.Contains("IList"))
                {
                    list.Add(Projections.Property(name), name);
                }
            }
        }          


It's possible in NHibernate 5.1 via Entity projections:

Title title = null;

var q = session
   .QueryOver(() => title)
   .Select(
      Projections.Entity(() => title),
      Projections.SubQuery(sq.Where(tt => tt.Id == title.Id))), "TopLevelGenre")
)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜