0

FluentNHibernate:1.3.0.733
NHibernate的:3.3.1.4000FluentNHibernate:ID列名稱忽略

嘗試設置列名的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列名稱。所以現在我有點失落。

回答

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和實體<> .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