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列名称。所以现在我是一个有点失落。
答案 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