0

FluentNHibernate:1.3.0.733
NHibernate:3.3.1.4000

我正在尝试设置Id 列的列名,但它似乎被忽略了


编辑:
找到解决方案。属性重新声明(新修饰符)是问题(见答案)。


我正在使用带有约定和覆盖的 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 列名。所以现在我有点迷失了.

4

1 回答 1

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<>.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;
    }

免责声明:此代码未经彻底测试。

我希望有一天有人可以免于调试时间!


华拉巴

于 2012-10-10T13:45:50.600 回答