FluentNHibernate:忽略Id列名称

时间:2012-10-10 11:29:18

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping automapping

FluentNHibernate:1.3.0.733
NHibernate:3.3.1.4000

尝试设置Id列的列名,但似乎被忽略


修改
找到解决方案。属性重新声明(new-modifier)是问题(见答案)。


我正在使用带有约定和覆盖的AutoMapping。

覆盖:

public class OrderHeadMapping : IAutoMappingOverride<OrderHead>
{
    public void Override(AutoMapping<OrderHead> mapping)
    {
        mapping.Schema("[database].[dbo]");
        mapping.Table("OrderHeads");            

        mapping.Id(x => x.Id, "desiredColumnName")              
            .Column("desiredColumnName")
            .GeneratedBy.UuidString();
        ...
    }
}

此代码已执行,但列名称仍为“Id”。

我已经将映射导出到目录中以查看结果:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" schema="[database].[dbo]" name="OrderHead, Core, Version=1.0.4666.19686, Culture=neutral, PublicKeyToken=null" table="OrderHeads">
    <cache usage="read-write" />
    <id name="Id" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="assigned" />
    </id>
    ...
  </class>
</hibernate-mapping>

我搜索了我的整个解决方案“.Id(”和“.Column(”以确保它不会意外重置,但没有结果涉及设置/覆盖id列名称。所以现在我是一个有点失落。

1 个答案:

答案 0 :(得分:0)

我终于找到了问题:
我在描述中遗漏的一件事是我有两个基本实体:

public abstract class Entity
{
    protected object _id;

    public virtual object Id
    {
        get { return _id; }
        protected internal set { _id = value; }
    }
}

public abstract class Entity<TKey> : Entity
{
    public Entity()
    {
        _id = default(TKey);
    }
    new public virtual TKey Id 
    {
        get { return (TKey)_id; }
        protected internal set { _id = (TKey)value; } 
    }
    ...
}

问题在于FluentNHibernate 处理重新定义的属性两次:Entity.Id和Entity&lt;&gt; .Id最终用基类版本的映射覆盖所需的映射 。 所以我必须走继承树以检查这个成员是否是最重写(如果有的话)。

现在我在ShouldMap的实施中使用DefaultAutomappingConfiguration方法处理问题:

public override bool ShouldMap(Member member)
{
    var res = base.ShouldMap(member);

    if (res == true)                
    {
        var originalDeclaringType = GetOriginalDeclaringType(member.MemberInfo);
        ...
        if(member.Name == "Id")
        {
            if (GetTopMostRedefinedMember(member.MemberInfo) != member.MemberInfo.DeclaringType)
                return false;
        }
    }           
    ...
    return res;
}

GetTopMostRedefinedMember为:

private Type GetTopMostRedefinedMember(MemberInfo member)
    {
        List<Type> types = new List<Type>();

        Type type = member.ReflectedType;
        while (type != null)
        {
            types.Add(type);
            type = type.BaseType;
        }

        foreach (var t in types)
        {
            var tmp = t.GetMember(member.Name, BindingFlags.Public |
                      BindingFlags.NonPublic |
                      BindingFlags.Instance |
                      BindingFlags.DeclaredOnly);
            if (tmp.Length != 0)
            {
                type = t;
                break;
            }
        }
        return type;
    }

免责声明:此代码未经过全面测试。

我希望有一天会有人安排调试时间!

LG
warappa