Fluent nhibernate 当属性和支持字段没有共同点时自动映射约定?
使用Fluent NHibernate,我似乎无法为以下(看似简单且常见)用例设计必要的自动映射约定:Fluent nhibernate 当属性和支持字段没有共同点时自动映射约定?,fluent-nhibernate,orm,Fluent Nhibernate,Orm,使用Fluent NHibernate,我似乎无法为以下(看似简单且常见)用例设计必要的自动映射约定: public class MyClass { private int _specialIdentityField private string _firstname; public Id { get { return _specialIdentityField; }; } public virtual string Firstname {
public class MyClass
{
private int _specialIdentityField
private string _firstname;
public Id { get { return _specialIdentityField; }; }
public virtual string Firstname
{
get
{
return _firstname;
}
set
{
_firstname = value;
}
}
}
public class OtherClass
{
private int _specialIdentityField
private string _lastname;
public Id { get { return _specialIdentityField; }; }
public virtual string Lastname
{
get
{
return _lastname;
}
set
{
_lastname = value;
}
}
}
所需的映射如下所示:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="field.camelcase-underscore" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="MyClass" table="`MyClass`">
<id name="_specialIdentityField" type="System.Int32" access=field>
<column name="Id" />
<generator class="identity" />
</id>
<property name="Firstname" type="System.String">
<column name="Firstname" />
</property>
</class>
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="OtherClass" table="`OtherClass`">
<id name="_specialIdentityField" type="System.Int32" access=field>
<column name="Id" />
<generator class="identity" />
</id>
<property name="Lastname" type="System.String">
<column name="Lastname" />
</property>
</class>
</hibernate-mapping>
基本上规则是:
- 除标识外,所有内容都以下划线作为访问类型
- 标识是每个类中的固定名称字段(名称=\u someSpecialIdentityField)
- 身份访问始终仅限于字段,与围绕它的RO属性的名称无关
这不可能是一个非典型的用例,所以我必须忽略一些非常明显的东西。感谢所有FNH大师的想法 编辑:查看IAutomappingConfiguration界面。创建自己的实现或重写DefaultAutomappingConfiguration类
public virtual bool IsId(Member member)
{
return member.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase);
}
然后将其添加到初始化中:
Fluently.Configure( Configuration )
.Mappings( cfg =>
{ cfg.AutoMappings.Add( IAutomappingConfigurationInstance )}
===============================================
嗨,史蒂夫,我想我知道你想做什么。我使用Proteus和FNH自动映射。为了使用id实现这个技巧,我在Proteus周围创建了一个包装器,它可以做两件事:
1) 映射ID
2) 隐藏id的Setter
public abstract class EntityObject<TEntity> : IdentityPersistenceBase<TEntity, Guid>, IEntity
where TEntity : class, IEntity
{
public virtual Guid Id
{
get { return _persistenceId; }
}
Guid IIdentifiedEntity<Guid>.Id
{
get { return _persistenceId; }
set { _persistenceId = value; }
}
public virtual int Version
{
get { return _persistenceVersion; }
set { _persistenceVersion = value; }
}
}
public抽象类EntityObject:IdentityPersistenceBase,entity
其中tenty:类,tenty
{
公共虚拟Guid Id
{
获取{return\u persistenceId;}
}
Guid IIIdentifiedIdentity.Id
{
获取{return\u persistenceId;}
设置{u persistenceId=value;}
}
公共虚拟整数版本
{
获取{return\u persistenceVersion;}
设置{u persistenceVersion=value;}
}
}
为了避免属性IsTransient被持久化+其他内容,您可以创建MappingAlternation:
public class EntityAlteration : IAutoMappingAlteration
{
public void Alter( AutoPersistenceModel model )
{
model.OverrideAll( map =>
{
Type recordType = map.GetType().GetGenericArguments().Single();
if( recordType.BaseType.Name == "EntityObject`1" )
{
Type changeType = typeof( Change<> ).MakeGenericType( recordType );
var change = ( IChange )Activator.CreateInstance( changeType );
change.Go( map );
}
} );
}
}
interface IChange
{
void Go( object mapObject );
}
class Change<TRecord> : IChange where TRecord : EntityObject<TRecord>
{
void IChange.Go( object mapObject )
{
var map = ( AutoMapping<TRecord> )mapObject;
map.Id( x => x.Id ).GeneratedBy.Guid().Access.Property();
map.IgnoreProperty( x => x.IsTransient );
}
}
公共类实体变更:IAutomapping变更
{
public void Alter(AutoPersistenceModel模型)
{
model.OverrideAll(map=>
{
类型recordType=map.GetType().GetGenericArguments().Single();
if(recordType.BaseType.Name==“EntityObject`1”)
{
类型changeType=typeof(Change).MakeGenericType(recordType);
var change=(IChange)Activator.CreateInstance(changeType);
改变。去(地图);
}
} );
}
}
界面易变
{
void Go(对象映射对象);
}
类更改:IChange其中TRecord:EntityObject
{
void IChange.Go(对象映射对象)
{
变量映射=(自动映射)映射对象;
map.Id(x=>x.Id).GeneratedBy.Guid().Access.Property();
map.IgnoreProperty(x=>x.IsTransient);
}
}
PS:我真的很怀念你在网上活跃的时光。这是一个激动人心的夏天,两年前的作者……编辑:看看IAutomappingConfiguration界面。创建自己的实现或重写DefaultAutomappingConfiguration类
public virtual bool IsId(Member member)
{
return member.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase);
}
然后将其添加到初始化中:
Fluently.Configure( Configuration )
.Mappings( cfg =>
{ cfg.AutoMappings.Add( IAutomappingConfigurationInstance )}
===============================================
嗨,史蒂夫,我想我知道你想做什么。我使用Proteus和FNH自动映射。为了使用id实现这个技巧,我在Proteus周围创建了一个包装器,它可以做两件事:
1) 映射ID
2) 隐藏id的Setter
public abstract class EntityObject<TEntity> : IdentityPersistenceBase<TEntity, Guid>, IEntity
where TEntity : class, IEntity
{
public virtual Guid Id
{
get { return _persistenceId; }
}
Guid IIdentifiedEntity<Guid>.Id
{
get { return _persistenceId; }
set { _persistenceId = value; }
}
public virtual int Version
{
get { return _persistenceVersion; }
set { _persistenceVersion = value; }
}
}
public抽象类EntityObject:IdentityPersistenceBase,entity
其中tenty:类,tenty
{
公共虚拟Guid Id
{
获取{return\u persistenceId;}
}
Guid IIIdentifiedIdentity.Id
{
获取{return\u persistenceId;}
设置{u persistenceId=value;}
}
公共虚拟整数版本
{
获取{return\u persistenceVersion;}
设置{u persistenceVersion=value;}
}
}
为了避免属性IsTransient被持久化+其他内容,您可以创建MappingAlternation:
public class EntityAlteration : IAutoMappingAlteration
{
public void Alter( AutoPersistenceModel model )
{
model.OverrideAll( map =>
{
Type recordType = map.GetType().GetGenericArguments().Single();
if( recordType.BaseType.Name == "EntityObject`1" )
{
Type changeType = typeof( Change<> ).MakeGenericType( recordType );
var change = ( IChange )Activator.CreateInstance( changeType );
change.Go( map );
}
} );
}
}
interface IChange
{
void Go( object mapObject );
}
class Change<TRecord> : IChange where TRecord : EntityObject<TRecord>
{
void IChange.Go( object mapObject )
{
var map = ( AutoMapping<TRecord> )mapObject;
map.Id( x => x.Id ).GeneratedBy.Guid().Access.Property();
map.IgnoreProperty( x => x.IsTransient );
}
}
公共类实体变更:IAutomapping变更
{
public void Alter(AutoPersistenceModel模型)
{
model.OverrideAll(map=>
{
类型recordType=map.GetType().GetGenericArguments().Single();
if(recordType.BaseType.Name==“EntityObject`1”)
{
类型changeType=typeof(Change).MakeGenericType(recordType);
var change=(IChange)Activator.CreateInstance(changeType);
改变。去(地图);
}
} );
}
}
界面易变
{
void Go(对象映射对象);
}
类更改:IChange其中TRecord:EntityObject
{
void IChange.Go(对象映射对象)
{
变量映射=(自动映射)映射对象;
map.Id(x=>x.Id).GeneratedBy.Guid().Access.Property();
map.IgnoreProperty(x=>x.IsTransient);
}
}
PS:我真的很怀念你在网上活跃的时光。这是一个激动人心的夏天,2年前的作者……wow——完美,如果不是有点过于复杂的话!关于我离开onli的事