代码之家  ›  专栏  ›  技术社区  ›  Christian Specht

如何在NHibernate映射类中查找未映射的属性?

  •  4
  • Christian Specht  · 技术社区  · 14 年前

    我刚刚遇到了一个与NHibernate相关的问题,我忘记映射类的一个属性。

    一个非常简单的例子:

    public class MyClass
    {
        public virtual int ID { get; set; }
        public virtual string SomeText { get; set; }
        public virtual int SomeNumber { get; set; }
    }
    

    …和映射文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                       assembly="MyAssembly"
                       namespace="MyAssembly.MyNamespace">
    
        <class name="MyClass" table="SomeTable">
            <property name="ID" />
            <property name="SomeText" />      
        </class>
    
    </hibernate-mapping>
    

    在这个简单的示例中,您可以立即看到问题:
    类中有一个名为“someNumber”的属性,但映射文件中没有。
    所以NHibernate不会映射它,它总是为零。

    真正的类有更多的属性,所以问题并不是那么容易看到,我花了很长时间才弄明白为什么somenumber总是返回零,即使我100%确定数据库中的值是!=零。

    所以,我的问题是:

    有什么简单的方法可以通过NHibernate找到这个吗?
    类似于类被映射时的编译器警告,但它的某些属性不是。
    或者一些我可以运行的查询,它显示了映射类中未映射的属性……你明白了。

    (另外,如果我能排除一些我 真正地 不需要映射。)

    编辑:
    好吧,我查看了你提出的所有内容,并决定使用元数据API……这对我来说是最容易理解的。
    现在我知道要搜索什么了,我找到了一些帮助我开始工作的例子。
    到目前为止,我有:

    Type type = typeof(MyClass);
    
    IClassMetadata meta = MySessionFactory.GetClassMetadata(type);
    
    PropertyInfo[] infos = type.GetProperties();
    
    foreach (PropertyInfo info in infos)
    {
        if (meta.PropertyNames.Contains(info.Name))
        {
            Console.WriteLine("{0} is mapped!", info.Name);
        }
        else
        {
            Console.WriteLine("{0} is not mapped!", info.Name);
        }
    }
    

    它几乎可以工作,除了一件事: iclassMetadata.propertyNames返回所有属性的名称 除了 ID.
    要获取ID,我必须使用IClassMetadata.IdentifierPropertyName。

    是的,我可以在新数组中保存.propertyname,向它添加.identifierpropertyname并搜索 那个 数组。
    但我觉得这很奇怪。
    没有比这更好的方法了吗 全部的 包含ID的映射属性?

    2 回复  |  直到 14 年前
        1
  •  6
  •   Stefan Steinegger    14 年前

    可以使用nhibernate元数据API查找映射的属性,并使用反射查找所有属性。

    编辑 不,没有任何其他方法可以列出包括ID在内的所有属性。使用起来并不难:

    foreach (PropertyInfo info in infos)
    {
        if (meta.PropertyNames.Contains(info.Name) || info.Name = meta.IdentifierPropertyName)
        {
            Console.WriteLine("{0} is mapped!", info.Name);
        }
        else
        {
            Console.WriteLine("{0} is not mapped!", info.Name);
        }
    }
    
        2
  •  1
  •   Jamie Ide    14 年前

    我知道有两种工具可以帮助解决这一问题:

    但它们并没有专门解决您对未映射属性的问题。最好的解决方案是编写好的单元测试,以确保要持久化的属性被正确地持久化。这很乏味,但很有必要。