Как перечислить имена столбцов с помощью NHibernate? - PullRequest
4 голосов
/ 16 апреля 2009

У меня есть класс с кучей атрибутов [ColumnName ("foo")] NHibernate. Есть ли простой способ попросить NHibernate перечислить все ColumnNames для данного класса?

Похоже, это должно быть действительно легко, но я просто не вижу никаких проверок в документах NHibernate (или, может быть, я просто слепой сегодня).

Ответы [ 4 ]

7 голосов
/ 12 июня 2009

У меня была такая же проблема, но я обнаружил, что IClassMetadata не имеет никакой информации о столбцах, только типы свойств, имена, идентификаторы и данные таблиц.

Что сработало для меня:

PersistentClass persistentClass = cfg.GetClassMapping(typeof(MyEntity));
Property property = persistentClass.GetProperty(propertyName);
property.ColumnIterator   // <-- the column(s) for the property
6 голосов
/ 08 декабря 2011

Как получить имена столбцов базы данных для сущности, сопоставленной NHibernate:

using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Persister.Entity;

namespace Stackoverflow.Example
{
    /// <summary>
    /// NHibernate helper class
    /// </summary>
    /// <remarks>
    /// Assumes you are using NHibernate version 3.1.0.4000 or greater (Not tested on previous versions)
    /// </remarks>
    public class NHibernateHelper
    {
        /// <summary>
        /// Gets the list of database column names for an entity
        /// </summary>
        /// <param name="sessionFactory">NHibernate SessionFactory</param>
        /// <param name="entity">A mapped entity</param>
        /// <returns>List of column names</returns>
        public static IEnumerable<string> GetPropertyColumnNames(ISessionFactory sessionFactory, object entity)
        {
            Type entityType = entity == null ? null : entity.GetType();

            List<string> columnNameList = null;

            // This has some cool methods and properties so check it out
            var metaData = entityType == null ? null : sessionFactory.GetClassMetadata(entityType.ToString());

            //- metaData validity check ... will be null if provided type is not mapped
            if (metaData != null)
            {
                // This has some even cooler methods and properties so definitely check this out
                var entityPersister = (AbstractEntityPersister) metaData;

                //- how to get the entity's identifier
                //- string entityIdentifier = metaData.IdentifierPropertyName;

                //- Get the database identifier
                //- can have multiple in case of composite keys
                IEnumerable<string> dbIdentifierNameList = entityPersister.KeyColumnNames;

                var propertyNameList = entityPersister.PropertyNames;

                // Adding the database identifier first
                columnNameList = new List<string>(dbIdentifierNameList);
                //- then add properties column names
                foreach (var propertyName in propertyNameList)
                {
                    var columnNameArray = entityPersister.GetPropertyColumnNames(propertyName);
                    columnNameList.AddRange(columnNameArray.Where(columnName => dbIdentifierNameList.Contains(columnName) == false));
                }
            }

            return columnNameList;
        }
    }
}   

Использование:

// Get your NHiberate SessionFactory wherever that is in your application
var sessionFactory = NHibernateHelper.SessionFactory;

// Get an entity that you know is mapped by NHibernate
var customer = new Customer();

// Get a list of the database column names for the entity
var columnNames = 
        Stackoverflow.Example.NHibernateHelper.GetPropertyColumnNames( sessionFactory, customer );

Греться во славе этой удивительности :)

2 голосов
/ 16 апреля 2009

Использование метаданных NHibernate

// get an instance to the metadata 
IClassMetadata metadata = sessionfactory.GetClassMetadata(typeof(MyEntity));

// use properties and methods from the metadata:
// metadata.PropertyNames
// metadata.PropertyTypes
// metadata.GetIdentifier()
// and more

// or get the metadata for all classes at once
IDictionary allClassMetaData = factory.GetAllClassMetadata();
metadata = allClassMetaData[typeof(MyEntity)];

Вы получаете то, что на самом деле знает NHibernate, независимо от того, как оно определено; используя атрибуты, сопоставления xml или FluentNHibernate . Это делает его более стабильным и надежным, чем использование отражения самостоятельно.

2 голосов
/ 16 апреля 2009

Использовать LINQ и отражение:

var columns = typeof(TheClass).GetProperties()
    .Where(property => property.GetCustomAttributes(typeof(ColumnNameAttribute), false).Count > 0)
    .Select(property => property.Name);
...