0

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列名の設定/上書きを扱う結果はありません。だから今、私は少し迷っています.

4

1 に答える 1

0

私は最終的に問題を発見しました:
私の説明で省略したことの 1 つは、2 つの基本エンティティがあることです。

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が再定義されたプロパティを 2 回処理することでした: 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 に答える